繁体   English   中英

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

[英]Hibernate/Ehcache: evicting collections from 2nd level cache not synchronized with other DB reads

我有一个使用JPA,Hibernate和ehcache以及Spring的声明式事务的应用程序。 数据库上的负载相当高,因此所有内容都被缓存以加快处理速度,包括收集。 现在,将集合与拥有它们的实体分开进行缓存不是什么秘密,因此,如果我删除作为该缓存集合的元素的实体,保留应该作为其中一个元素的实体,或者更新一个实体,使其成为实体从一个收藏品到另一个收藏品,我得亲自进行驱逐。

因此,我使用了一个休眠事件侦听器,该侦听器跟踪插入,删除或更新的实体,并保存该信息以供在Spring的事务管理器中注册的事务同步操作。 事务一旦提交,同步就会执行收回。

现在的问题是 ,很多其他并发事务经常设法在缓存中找到一个刚刚被收回的集合(根据日志,这些事件通常相差十分之一秒),并且自然会导致EntityNotFoundException的发生。

如何正确同步这些内容?

我尝试在TransactionSynchronization的4种方法中的每种方法中逐出(它们在相对于事务完成的不同时间点调用),但无济于事。

本质上,您需要做的是在收集正在进行或刚刚被收回时,强制从数据库中进行读取。 一种方法是在收到撤离请求后立即将其标记为脏,但在进入更改它的交易之前。 随之而来的任何并发事务都将检查脏标志,如果将其设置为true,则应从数据库获取数据,否则可以从缓存中读取数据。 您可能需要更改数据库事务设置,以便并发事务一直阻塞到更新数据完成为止,以便从数据库读取正确的数据。 事务完成后,您可以将脏标志重置为false。

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

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

还是我错过了什么? 您为什么不能简单地使收藏集保持最新状态?

我认为您必须参考此链接:- 休眠:清理收集的二级缓存,而级联删除项则显示 ,休眠实际上并没有从缓存中删除对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM