2009-08-17 16 views
1

我們使用Hibernate運行JBoss並遇到了這個問題。如何在JBoss中以一致的狀態維護Hibernate的EntityManager緩存?

當會話bean使用EntityManager來查找實體時,它可能已經存在於EntityManager的緩存中,並且它的狀態可能已經過時。如果代碼使用這樣一個實體來做出決定,它可能會做出錯誤的決定,從而產生錯誤。

這裏是一個例子。

HTTP請求1.一種會話bean創建實體實例,並使用字段存儲爲「A」設定爲值1。持久實體獲取ID = 4。

HTTP請求2.會話bean查找一個ID = 4的實體將其字段「A」設置爲值2並保存。

HTTP請求3.會話bean查找ID = 4的實體並檢查它的字段「A」。如果值是1,它會做一件事,如果它是2,它會做另一件事。

如果請求3中的EM碰巧與請求1中的EM相同,則會發生不希望的行爲。我測試了這一點,並得到了約。 10%的失敗案例。

所以問題是 - 如何避免這種情況?每次我必須確保實體是最新的時,調用em.refresh()或em.clear()似乎是浪費資源。

回答

1

阿爾喬姆,

這似乎是一個recurringtheme您的問題:-)

中雖然我明白,你已經給出答案之前(包括我)可能不是你所希望看到的,他們不會改變:

  • 實體管理器映射到Hibernate會話,通常需要是短暫的。 Here是關於Hibernate會話的工作單元,事務和範圍的一個很好的解釋,看看你以前沒見過它。
  • 如果您的申請是一致堅持實體經理,您需要認真考慮更改該策略;如果你只是在幾個需要長時間交易的地方使用這個方法,那麼這個方法肯定是所有惡意中較小的一個。
  • 不同於其具有羣集實現中second level cache,會話級高速緩存未diferent會話(實體管理器)通過設計和併發更新通過由休眠或應用程序級的鎖定提供optimistic locking的處理相同的實體之間同步。
  • 您可以在理論上(假設您的ORM訪問已分離得足夠好)維護各個實體管理器擁有的實體緩存(如果需要,可以分組);您需要註冊適當的event listeners以保持緩存同步。儘管如此,我強烈反對這種方法 - 不僅涉及到實現和錯誤發生,而且還會違背Hibernate的範式。
+0

謝謝你的耐心和樂於助人。我意識到我一直在問錯誤的問題。這裏是我真正的理由:http://stackoverflow.com/questions/1293429/how-to-force-jboss-4-2-3-to-clear-hibernates-session-cache-for-every-request。對不起,這樣的一個白癡。 – artemb 2009-08-18 12:10:06

+0

沒有什麼關於你的問題 - 整個會話緩存的事情是相當混亂的:-)我在上面的問題留下了一個評論,也許它會有所幫助 - 我不是自己使用CMP,所以我不太確定如何改變實體經理的範圍;這絕對是一個配置/部署問題,但我相信有人會回答你的問題。祝您好運。 – ChssPly76 2009-08-18 15:26:56