2010-07-27 31 views
5

Có 19 phương pháp trong lớp DAO chúng tôi, mỗi một số biến thể của này:Cách thích hợp để đảm bảo kết nối EntityManager bị đóng là gì?

public TicketProp saveTicketProp(TicketProp prop) { 
    EntityManager em = this.emf.createEntityManager(); 
    try { 
     em.getTransaction().begin(); 
     prop = (TicketProp) em.merge(prop); 
     em.getTransaction().commit(); 
     return prop; 
    } finally { 
     em.close(); 
    } 
} 

Ý nghĩa: Trong mỗi phương pháp chúng tôi xử lý giao dịch của chúng ta và đóng nó trong một khối finally. Chúng tôi đang thử nghiệm một ứng dụng Jersey, vì vậy các thử nghiệm JUnit của chúng tôi mở rộng JerseyTest. Mỗi phương pháp thử nghiệm instantiates một container Grizzly, chạy thử nghiệm, sau đó tắt container. EntityManagerFactory được tiêm vào mùa xuân. Chúng tôi đang sử dụng JPA trên Hibernate.

Tôi đang giám sát các kết nối với DB kiểm tra MySQL của chúng tôi và chúng luôn cao. Chỉ một thử nghiệm chạy biến "Max_used_connections" của MySQL là 38. Để giải trí, tôi đã đi và nhận xét tất cả các cuộc gọi em.close() và thử nghiệm vẫn sử dụng 38 kết nối.

Tôi đang sử dụng tính năng tổng hợp kết nối được tích hợp sẵn của Hibernate (không dành cho việc sử dụng sản phẩm, tôi biết). Tôi vẫn mong đợi một số loại tổng hợp thông minh.

Tôi có xử lý EntityManager không? Tôi có thể đóng kết nối bằng cách nào khác?

+0

em.close chỉ phát hành kết nối đến hồ bơi kết nối. emf.close sẽ đóng tất cả các kết nối. vì vậy có thể có quá nhiều emf tạo ra trong ứng dụng của bạn để có quá nhiều kết nối. – Scarlett

Trả lời

2

Tại sao bạn cho rằng EntityManager.close() luôn đóng kết nối cơ bản? Đó là vào hồ bơi kết nối (bạn có thể cần phải cấu hình nó và thiết lập số lượng tối đa các kết nối mở đồng thời).

5

Bạn nên close số EntityManagerFactoryvào cuối thử nghiệm. Từ javadoc của EntityManagerFactory#close():

void javax.persistence.EntityManagerFactory.close() 

Đóng nhà máy, phát hành bất kỳ nguồn lực mà nó nắm giữ. Sau khi một trường hợp nhà máy đã được đóng lại, tất cả các phương thức được viện dẫn trên nó sẽ ném IllegalStateException, ngoại trừ isOpen, sẽ trả về false. Khi một EntityManagerFactory đã bị đóng, tất cả các nhà quản lý thực thể của nó được coi là ở trạng thái đóng.

Là một mặt lưu ý, bạn thực sự nên rollback giao dịch trước khi chốt EM trong mệnh đề finally:

public TicketProp saveTicketProp(TicketProp prop) { 
    EntityManager em = this.emf.createEntityManager(); 
    try { 
     em.getTransaction().begin(); 
     prop = (TicketProp) em.merge(prop); 
     em.getTransaction().commit(); 
     return prop; 
    } finally { 
     if (em.getTransaction().isActive()) { 
      em.getTransaction().rollback(); 
     } 

     if (em.isOpen()) { 
      em.close(); 
     } 
    } 
} 
+0

Giao dịch sẽ không tự động được khôi phục trong trường hợp Ngoại lệ? Khối cuối cùng của tôi có ngăn chặn điều đó không? – gmoore

+2

@gmoore: Trong trường hợp ngoại lệ JPA, có. Nhưng còn những người khác thì sao? Tôi xem xét gọi rollback trong khối cuối cùng là một thực hành tốt. –

+0

yes, em.close chỉ phát hành kết nối với nhóm kết nối. emf.close sẽ đóng tất cả các kết nối. vì vậy có thể có quá nhiều emf tạo ra trong ứng dụng của bạn để có quá nhiều kết nối. – Scarlett

Các vấn đề liên quan