2010-07-27 22 views
5

DAO katmanımızda 19 metot vardır, bunların her biri bir çeşittir:EntityManager bağlantılarının kapalı olmasını sağlamanın doğru yolu nedir?

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(); 
    } 
} 

Anlamı: Her bir yöntemde kendi işlemimizi gerçekleştirir ve sonunda bir blokta kapatırız. Bir Jersey uygulamasını test ediyoruz, bu yüzden JUnit testlerimiz JerseyTest'i uzatıyor. Her test metodu Grizzly konteynerini başlatır, testi çalıştırır ve daha sonra kabı kapatır. EntityManagerFactory bahar tarafından enjekte edilir. Hazırda bekleyenler için JPA kullanıyoruz.

MySQL test veritabanımızın bağlantılarını izliyorum ve her zaman yüksekler. Tek bir test sadece MySQL "Max_used_connections" değişkenini 38 olarak değiştirir. Eğlenmek için, tüm em.close() çağrılarına gittim ve yorum yaptım ve test hala 38 bağlantı kullanıyor.

Hibernate'in yerleşik bağlantı havuzunu kullanıyorum (prod kullanmak için değil, biliyorum). Hala bir çeşit akıllı havuz bekliyorum.

EntityManager'ı yanlış mı kullanıyorum? Bağlantıları başka nasıl kapatabilirim?

+0

em.close tek bağlantı havuzuna bağlantı bırakın. emf.close tüm bağlantıları kapatır. Bu yüzden uygulamanızda çok fazla emf olabilir, bu yüzden çok fazla bağlantı var. – Scarlett

cevap

2

Neden EntityManager.close()'un neden her zaman altta yatan bağlantıyı kapattığını düşünüyorsunuz? Bağlantı havuzuna bağlı (muhtemelen bunu yapılandırmanız ve aynı anda açık bağlantıların maksimum sayısını ayarlamanız gerekir).

5

testinizin sonunda EntityManagerFactoryclose'u kullanmalısınız.

void javax.persistence.EntityManagerFactory.close() 

Kapat fabrikada, bu tutar tüm kaynakları serbest: EntityManagerFactory#close() ait javadoc itibaren. Bir fabrika örneği kapatıldıktan sonra, üzerinde çalıştırılan tüm yöntemler, isOpen hariç, IllegalStateException'u atar ve bu da false değerini döndürür. Bir EntityManagerFactory kapatıldıktan sonra, tüm varlık yöneticilerinin kapalı durumda olduğu kabul edilir. Bir yan not olarak

, gerçekte finally fıkrada EM kapatmadan önce geri alma hareketi olmalıdır:

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

İşlemler, bir İstisna durumunda otomatik olarak geri alınmaz mı? Sonunda benim engelleme engel mi? – gmoore

+2

@gmoore: JPA istisnası durumunda, evet. Peki ya diğerleri? Son olarak blokta geri dönüşün iyi bir uygulama olduğunu düşünmeyi düşünüyorum. –

+0

evet, em.close sadece bağlantı havuzuna bağlantıyı serbest bırakır. emf.close tüm bağlantıları kapatır. Bu yüzden uygulamanızda çok fazla emf olabilir, bu yüzden çok fazla bağlantı var. – Scarlett

İlgili konular