Hibernate / Ehcache:从第二级缓存中驱逐集合,与其他数据库读取不同步

时间:2009-10-01 19:22:36

标签: java hibernate collections transactions ehcache

我有一个使用JPA,Hibernate和ehcache的应用程序,以及Spring的声明 交易。 DB上的负载相当高,因此所有内容都被缓存以加快速度, 包括收藏品。现在,收集单独缓存并不是秘密 来自拥有它们的实体,如果我删除了一个实体的实体 缓存集合,持久化应该是其中一个元素的实体,或更新一个 实体,它从一个集合到另一个集合,我必须执行驱逐 用手。

所以我使用了一个hibernate事件监听器来跟踪被插入,删除的实体 或更新并保存该信息以用于向Spring注册的事务同步 交易经理采取行动。然后同步执行驱逐一次 交易已经提交。

现在问题是,很多时候,其他一些并发事务设法找到了 刚刚被驱逐的缓存中的一个集合(这些事件通常是十分之一 根据日志分开第二个,自然会导致发生EntityNotFoundException。

如何正确同步这些内容?

我尝试在TransactionSynchronization的4种方法中进行驱逐(其中 在相对于交易完成的不同时间点被调用),它没有帮助。

3 个答案:

答案 0 :(得分:3)

基本上,您需要做的是在集合处于流程中或刚刚被驱逐的情况下强制从数据库读取数据。实现此目的的一种方法是,一旦收到驱逐它的请求但在进入交易之前将其更改为脏,就将其标记为脏。任何并发的事务都会检查脏标志,如果设置为true,它应该从数据库获取数据,否则它可以从缓存中读取。您可能需要更改数据库事务设置,以便并发事务阻塞,直到更新数据完成为止,以便从数据库中读取正确的数据。事务完成后,您可以将脏标志重置为false。

只要驱逐持续到更新,插入或删除,您也可以在缓存集合上创建锁定。这将确保在驱逐过程完成之前,没有其他事务可以读取/更改缓存的集合。

答案 1 :(得分:0)

为什么你不能让收藏保持最新?即添加对象时,将对象添加到它所属的集合中。当你删除一个对象时,将它从它所在的集合中删除。根据我的经验,当使用带有hibernate或jpa的缓存时,对象的状态(而不是数据库的状态)被缓存,因此你需要确保你的对象模型在内存中与数据库中的对象模型同步。

或者我错过了什么?为什么你不能简单地保持收藏的最新状态?

答案 2 :(得分:0)

我认为你必须参考这个链接: - Hibernate: Clean collection's 2nd level cache while cascade delete items 看,hibernate实际上并没有从缓存中删除对象..其余的你可以从上面的链接中得到答案