已删除软锁定缓存条目。失衡锁定/解锁序列?

时间:2012-10-23 14:18:32

标签: java spring hibernate ehcache

我使用的是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 ?

什么可以产生这个错误?

2 个答案:

答案 0 :(得分:3)

我现在正受到这种打击,所以我会分享我的发现。

首先,一些背景知识:

  • 我们使用Hibernate 3.5.2& EhCache 2.7.0
  • 只有一个数据库(另一个数据库仅供读取,但没有使用缓存,因为它在外部更新),单个缓存实例(无群集)
  • 更新使用InheritanceType.JOINED和CacheConcurrencyStrategy.READ_WRITE映射的实体时会出现问题(但是当我们切换到NONSTRICT_READ_WRITE时则不会)。此外,从代码检查来看,它也会在删除时发生。

通过调试Hibernate和EhCache代码我发现了什么:

  1. Hibernate的EntityUpdateAction(在execute()中)调用EntityRegionAccessStrategy.lockItem()
  2. EhCache的实现(在AbstractReadWriteEhcacheAccessStrategy中)将给定键的映射从缓存实体更改为锁
  3. Hibernate检测到该实体被映射到多个表,因此需要缓存失效(请参阅AbstractEntityPersister.isCacheInvalidationRequired())
  4. 继续调用persister.getCacheAccessStrategy()。remove(),在EhCache的实现中,删除给定缓存键的映射。但是,虽然Hibernate希望这实际上会删除缓存的实体,但是使用EhCache它会删除锁(在第2步中放置了锁)。
  5. 事务完成后,在EntityUpdateAction.doAfterTransactionCompletion()中,Hibernate检测到需要缓存失效,并继续调用unlockItem(),如果没有给定缓存键的映射,则会失败,导致您描述的错误消息
  6. 在我看来,这是在lockItem()和unlockItem()的EhCache实现中的一个问题(在READ_WRITE情况下)。它不应该用锁替换实际项目,而是分别存储锁。至少,可以说Hibernate和EhCache在这种情况下不是100%兼容。

    最后几点说明:

    • 似乎这个错误是无害的,可以通过log4j config安全地抑制。
    • 我设法在不同的场景中重复这一点(归结为相同的锁定/删除/解锁序列)。这次,本机SQL触发了删除,而不是连接继承。其他一切都差不多。
    • Hibernate和EhCache代码的相关部分:EntityRegionAccessStrategy,EntityAction,CollectionRegionAccessStrategy,CollectionAction以及相关的实现/扩展具体类。

    HTH

答案 1 :(得分:2)

当我使用createSQLQuery(Native SQL Query)时,我遇到了同样的问题。感谢这个Impact of native sql queries on hibernate's second level cache,我解决了我的问题。

从链接:主要原因是本机查询可以使第二级缓存无效。链接底部还有解决方案,以防止在使用本机sql查询时hibernate使L2缓存无效。