【问题标题】:A soft-locked cache entry was removed already. Out of balance lock/unlock sequences?已删除软锁定缓存条目。失衡锁定/解锁序列?
【发布时间】:2012-10-23 14:18:31
【问题描述】:

我正在使用 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 ?

什么会导致这个错误?

【问题讨论】:

  • hibernate 3.6.10Final 也有同样的问题(与 ehcache 2.x 更兼容)

标签: java spring hibernate ehcache


【解决方案1】:

我现在很受打击,所以我会分享我的发现。

首先,一些背景:

  • 我们使用 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(),如果没有给定缓存键的映射,则会失败,从而导致您描述的错误消息李>

在我看来,这是 lockItem() 和 unlockItem() 的 EhCache 实现中的一个问题(在 READ_WRITE 情况下)。它不应该用锁代替实际的物品,而是单独存储锁。至少,可以说 Hibernate 和 EhCache 在这种情况下不是 100% 兼容的。

最后几点说明:

  • 似乎这个错误是无害的,可以通过 log4j 配置安全地抑制。
  • 我已设法在不同的场景中重复此操作(归结为相同的锁定/删除/解锁序列)。这一次,不是加入继承,而是原生 SQL 触发了删除。其他一切都差不多。
  • Hibernate 和 EhCache 代码的相关位:EntityRegionAccessStrategy、EntityAction、CollectionRegionAccessStrategy、CollectionAction 和相关的实现/扩展具体类。

HTH

【讨论】:

    【解决方案2】:

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

    来自链接:主要原因是原生查询会使二级缓存失效。链接底部还有解决方案,防止hibernate在使用原生sql查询时使二级缓存失效。

    【讨论】:

    • Rene,这个问题在 hibernate 4.x 中仍然存在吗?
    猜你喜欢
    • 2011-08-06
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-21
    • 2017-02-20
    • 2015-01-02
    • 1970-01-01
    • 2012-12-25
    相关资源
    最近更新 更多