2011-08-15 37 views
5

鑑於:簡單的JSF webapp(無Seam),讓JSF bean調用幾個EJB,然後加載並保留JPA實體。我想是使用@Singleton註解爲EJB的和注入的EntityManager代替EntityManagerFactoryEJB 3.1 Singleton + JPA + JSF需要的設計建議

@Singleton 
public class MyEJB { 
    @PersistenceContext(unitName = PERSISTENCE_UNIT_NAME) 
    protected EntityManager em; // not EntityManagerFactory 
} 

規範說@Singleton是線程安全的,支持併發性和事務屬性,這些屬性(從我的POV)使得它的安全從JSF bean中調用。我期望還有性能優勢,因爲每次調用都不會重新創建EntityManager,這是內部緩存功能。

我的主要關注點是在我有幾個單身人士的情況下對JPA實體進行創建/更新操作,結果導致長壽命的EntityManagers數量相同。

  • 如果一個單身人士更新JPA實例以及這些 更改如何填充到其他單身人士會發生什麼情況?
  • 由於我無法關閉實體管理器,我是否需要在每個實體更新時沖洗它 ?
  • 如果這幾個單身人士會共用同一個實體 經理,會更好嗎?
  • 我只看到了這樣的設計的幾個例子。爲什麼?有沒有嚴重的 缺點?

非常感謝提前!

回答

5

我還期望性能優勢,因爲EntityManager不會爲每個調用重新創建,而且它是內部緩存功能。

你可能會使用的單身,卻處處用它在你的應用程序可以使它實際上更慢,因爲只有一個EJB服務全部由您的應用程序的各種用戶的併發請求節省一些內存時,集裝箱門鎖訪問到EJB,並且當它忙於提供請求時,它不能提供另一個請求。然而,這可以使用鎖類型(即@Lock(WRITE)@Lock(READ))在一定程度上得到緩解。當您要執行一段代碼,請定期使用EJB計時器,或者定期更新緩存等

單身人士對時代有用

如果一個單身更新的JPA實例以及如何將這些會發生什麼更改填充到其他單身人士?

與非單例EJB的行爲方式應該沒有什麼不同。

由於我無法關閉實體管理器,我是否需要在每次實體更新時刷新它?

如果您使用CMT,在每次交易結束時,所有內容都將自動刷新。

如果這幾個單身人士會共享相同的實體經理,會更好嗎?

看起來像不成熟的優化給我。只需讓容器爲您注入EM即可。

我只看到了這樣的設計的幾個例子。爲什麼?有沒有嚴重的缺點?

已經解釋。

+0

這個答案很好,但如果您提到注入的EM實際上是每個事務EM的代理,它可能會清除混淆。請參閱http://stackoverflow.com/questions/7010470/ejb-3-1-transaction-entitymanager/7017915#7017915 –

+0

@bkail,Behrang感謝您的回答和評論。 – Osw

+0

@Osw:不客氣。 :) – Behrang

0

關於更改Singleton EJB的LockType有一點我想提到。雖然總的來說這聽起來像是一個好主意,但您應該記住像EntityManger這樣的資源不是線程安全的,因此應該提供適當的併發訪問控制。您可以使用@Lock(WRITE)註釋訪問非線程安全資源的方法,但是如果Singleton EJB的幾乎所有接口方法都訪問這些資源,那麼與完全寫入鎖定資源的情況幾乎相同。另一種方法是使用Bean Concurrency Management和手動細粒度同步,但這也是一個值得懷疑的決定。

因爲一般情況下,我更喜歡Singleton的無狀態EJB,並在特定情況下使用後者。