2011-02-14 74 views
4

我正在使用JBoss EAP 4.3。JBoss TreeCache的併發策略配置作爲第二級休眠緩存

當我使用內置的JBoss TreeCache作爲Hibernate的二級緩存時,我正在研究併發策略的不同選項。我已經設置了它,並且通過查看日誌證實緩存正在工作,但是我不確定實際使用的併發策略以及它的工作方式。

爲每個實體,我可以設置在@Cache註釋下面的 「使用」 值中的一個:NONEREAD_ONLYNONSTRICT_READ_WRITEREAD_WRITETRANSACTIONAL

在另一方面,我JBossTreeCache配置文件我可以設置IsolationLevel爲整個高速緩存執行下列操作之一:NONEREAD_UNCOMMITTEDREAD_COMMITTEDREPEATABLE_READSERIALIZABLE(或者只是使用OPTIMISTIC)。

在逐個查看配置選項時,文檔非常清晰,但我不知道將不同選項合併時會發生什麼情況。

例如,如果您爲實體設置@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL),但爲JBossTreecache配置NONEIsolationLevel,會發生什麼情況?

我也相信,JBossTreeCache只支持NONEREAD_ONLYTRANSACTIONAL使用,但什麼IsolationLevel是你允許他們結合?如果你使用例如NONSTRICT_READ_WRITE會發生什麼?

產品總數應該有像5x6至不同的組合在這裏,但不是所有的人都有道理..

能anyoone幫我整理了這一點?

回答

8

隔離級別是一個棘手的問題。

例如,如果您爲實體集@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)但對於JBossTreecache配置NONEIsolationLevel,會發生什麼?

大多數情況下,在生產中很難找到錯誤......您應該明白,通過使用讀寫緩存,您基本上可以在分佈式事務中使自己的所有「細節」變得沉悶。

好吧,關於組合: 當你的對象沒有改變時,應該使用Hibernate中的只讀緩存設置。例如,對於國家字典。緩存併發級別NONE或READ_ONLY應該與它一起使用。

當您的緩存對象發生變化時,應該使用非嚴格讀寫,但這種情況很少發生,競爭條件很小。例如,對於時區字典 - 時區可能會偶爾出現/消失,但這種情況一年可能會出現幾次。同樣,緩存併發級別NONE或READ_ONLY應該與它一起使用。

現在,更有趣的組合。

Transactional Hibernate中的緩存是不安全的,Hibernate假定緩存更新是事務性的,但是無法確保它。所以你必須使用一個全面的外部XA(分佈式事務)協調器,除非你真的知道自己在做什麼,否則你確實真的不需要它。很可能,您必須使用完整的EJB3容器來支持XA-manager,儘管可以使用外部事務管理器(如http://www.atomikos.com/)和純servlet + Spring。顯然,你需要使用TRANSACTIONAL緩存。

'READ_WRITE`是一個有趣的組合。在這種模式下,Hibernate本身就是一個輕量級的XA協調器,所以它不需要全面的外部XA。它如何工作的簡短說明:

  1. 在這種模式下,Hibernate自己管理事務。所有數據庫操作必須在事務中,自動提交模式將不起作用。
  2. flush()期間(可能會在事務生命週期中出現多次,但通常在提交之前發生),Hibernate會通過會話並搜索更新/插入/刪除的對象。然後這些對象首先被保存到數據庫中,然後被鎖定並在緩存中更新,所以併發事務既不能更新也不能讀取它們的
  3. 如果事務被回滾(顯式或由於某種錯誤),鎖定的對象只是從緩存中釋放並逐出,所以其他事務可以讀取/更新它們。
  4. 如果事務成功提交,則鎖定的對象將被簡單釋放,其他線程可以讀取/寫入它們。

這裏有幾個細微之處的:

可能重複讀違反。假設我們有事務A(tA)和事務B(tB)同時啓動,並且加載對象X和tA然後修改這個對象,然後提交tA。在許多使用快照隔離的數據庫(Oracle,PostgreSQL,FireBird)中,如果tB再次請求對象X,它應該接收與事務開始時相同的對象狀態。但是,READ_WRITE緩存可能會違反此條件 - 此處沒有快照隔離。 Hibernate嘗試通過在緩存對象上使用時間戳,但在定時器分辨率較差的操作系統(Windows上15.6ms)上使用時間戳,它可以保證讓一些種族溜走。

可能樂觀的陳舊對象版本 - 如果您非常不幸在Windows上工作並且有多個事務使用相同的時間戳進行提交,則可能會得到過時的對象版本。

+0

感謝您付出努力回答我的問題。然而,有幾件事對我來說並不清楚:你寫道「NONE或READ_ONLY應該與它一起使用」。你真的指的是JBossTreeCache嗎?我在JBossTreeCache中找不到READ_ONLY IsolationLevel。我還認爲JBossTreeCache不支持NONSTRICT_READ_WRITE和READ_WRITE Hibernate的用法。你能評論一下嗎? – Steve 2011-02-23 21:29:09