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

标签 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 ?

什么会产生这个错误?

最佳答案

我现在正受此困扰,所以我将分享我的发现。

首先,一些背景:

  • 我们使用 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 检测到实体映射到超过 1 个表,因此需要缓存失效(参见 AbstractEntityPersister.isCacheInvalidationRequired())
  4. 它继续调用 persister.getCacheAccessStrategy().remove(),在 EhCache 的实现中,它会删除给定缓存键的映射。然而,虽然 Hibernate 期望这实际上会删除缓存的实体,但使用 EhCache 它会删除锁(在第 2 步中放在那里。)
  5. 事务完成后,在 EntityUpdateAction.doAfterTransactionCompletion() 中,Hibernate 检测到需要使缓存失效,然后继续调用 unlockItem(),如果没有给定缓存键的映射,则调用失败,导致您描述的错误消息<

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

最后几点说明:

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

HTH

关于java - 已删除软锁定缓存条目。失衡的锁定/解锁序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13032552/

相关文章:

java - ClassNotFoundException 被 DriverManger.getConnection 抛出?

java - 如何使用端口号来保护 Web 请求

spring - Spring 不会发生 Autowiring

java - 创建具有名称的 bean 时出错

java - Hibernate + Json + 字符串数组

java - hibernate PropertyAccessException : Error accessing field when use @ManyToMany

java - 无法在 Spring Boot 应用程序中访问 REST API

java - Spring 启动 : Change the order of the PropertySource

java - swagger - 没有 API 的空列表

java - 如何在数据库中使用 hibernate 和 spring mvc 获取一些 utf-8 字符?