2010-08-03 258 views
14

我學習JPA和實例的一般模式似乎如下:保持JPA EntityManager打開?

EntityManager em = factory.createEntityManager(); 
em.getTransaction().begin(); 
// .... 
em.getTransaction().commit(); 
em.close(); 

現在我想知道爲什麼我們不斷創造和接近EntityManagers,而不是保持它的開放和剛剛開始新的交易?保持開放與始終關閉的好處和成本有哪些?

JPA特定

回答

7

兩個原因浮現在腦海中:

  1. 的EntityManager不能保證通過JPA規範是線程安全的。因此,便攜式JPA應用程序一次最多隻能使用一個EM。創建方法本地EM並在超出範圍之前將其關閉的習慣用法鼓勵EM引用的堆棧限制。

  2. 使用「擴展」持久性上下文生命週期的EM爲其整個存在維護單個持久性上下文。這意味着實體停止自動分離commit()。相反,他們必須手動分離,否則EM仍然負責跟蹤他們。

這個問題是一個真正的JPA特定版本的舊「何時池對象」的問題。這是一個艱難的,但答案可能是「很少」。

這個old developerWorks post由Java併發專家Brian Goetz闡述了這一點。要點:池對於昂貴的對象很有意義,比如數據庫連接。但對於像EntityManager這樣的短暫,小而快速初始化的對象,共享或其他形式的長期參考保留是一種難以推銷的方式。

但是,這是一個普遍的問題,所以肯定會有例外。也許應用程序很簡單或單線程。然後,這些關於線程安全性的擔憂變得沒有意義。

5

保持一個實體管理器打開可以防止它返回到連接池的連接。

這可能導致幾個問題,尤其是在web應用程序中,例如,當池運行已滿且達到最大連接大小時,其他用戶無法獲得阻止該用戶訪問數據庫的數據庫連接。

在這種情況下,最好有短生命實體經理,例如,在請求開始時打開實體管理器,並在請求結束時關閉它(可以用偵聽器/攔截器完成)。然後這些實體變成分離的,如果你想再次使用它們(使用實體管理器的合併操作),你必須重新附加它們。