2012-10-23 36 views
6

我使用java 1.6,spring 2.5,hibernate 3.3.1和ehcache 2.6.0。程序連接到兩個數據庫。有兩個ehcache配置,但在這種情況下只使用一個。 在批處理結束程序返回此錯誤:軟鎖定緩存條目已被刪除。失去平衡鎖定/解鎖序列?

2012-10-23 15:44:43,406 ERROR (AbstractReadWriteEhcacheAccessStrategy.java:159) - Cache dao.data.MyObject Key dao.data.MyObject#28 Lockable : null 
A soft-locked cache entry was removed already. Out of balance lock/unlock sequences ? 

什麼會產生這個錯誤?

+0

與hibernate 3.6.10Final(與ehcache 2.x更兼容)相同問題 – ratm

回答

3

我現在被這個打了,所以我會分享我的發現。

首先,一些背景:

  • 我們使用Hibernate 3.5.2 &的Ehcache 2.7.0
  • 只有一個(另一個用於只讀訪問的數據庫,但是沒有緩存使用那裏,因爲它是外部更新的)和單個緩存實例(無羣集)
  • 在更新使用InheritanceType.JOINED和CacheConcurrencyStrategy.READ_WRITE映射的實體(但不是在我們切換到NONSTRICT_READ_WRITE時)時會出現問題。另外,從代碼檢查來看,它也會在刪除時發生。

我已經通過調試發現和Hibernate的Ehcache代碼:

  1. Hibernate的EntityUpdateAction(在執行())調用EntityRegionAccessStrategy.lockItem()
  2. 的Ehcache的實現(AbstractReadWriteEhcacheAccessStrategy)改變映射給定密鑰從緩存實體到鎖
  3. Hibernate檢測到該實體映射到多個表,因此需要高速緩存失效(請參見AbstractEntityPersister.isCacheInvalidationRequired())
  4. 它繼續調用persister.getCacheAccessStrategy()。remove(),它在EhCache的實現中刪除給定緩存鍵的映射。然而,雖然Hibernate期望這將實際上刪除緩存實體,但使用EhCache時,它將刪除鎖(步驟2中已將其放在那裏)。
  5. 事務完成後,在EntityUpdateAction.doAfterTransactionCompletion()中,Hibernate檢測到緩存失效是需要,進入到調用unlockItem(),它失敗如果對於給定的緩存鍵的映射關係,從而導致錯誤消息,描述

在我看來,這是的Ehcache實現lockItem的問題()和unlockItem()(在READ_WRITE情況下)。它不應該用鎖代替實際的項目,而應單獨存儲鎖。至少,可以說在這種情況下Hibernate和EhCache不是100%兼容的。

最後幾個注意事項:

  • 看來,這個錯誤是無害的,可以通過log4j的配置可以安全地抑制。
  • 我已經設法在不同的情況下重複這個(歸結爲相同的鎖定/移除/解鎖序列)。這一次,不是加入繼承,而是一個本地SQL觸發了刪除。其他一切都差不多。
  • Hibernate和EhCache代碼的相關位:EntityRegionAccessStrategy,EntityAction,CollectionRegionAccessStrategy,CollectionAction和相關的實現/擴展具體類。

HTH

2

我,我使用createSQLQuery(原生SQL查詢)時,得到了同樣的問題。感謝這Impact of native sql queries on hibernate's second level cache,我解決了我的問題。

從鏈接:主要原因是本機查詢可以使二級緩存無效。鏈接底部還有一個解決方案,用於防止在使用本地SQL查詢時休眠狀態使L2緩存失效。

+0

Rene,這個問題對於hibernate 4.x仍然是實際的嗎? – Johnny