9

我有一个使用 JPA、Hibernate 和 ehcache 以及 Spring 的声明性事务的应用程序。DB 上的负载相当高,因此所有内容都被缓存以加快速度,包括集合。现在,集合与拥有它们的实体分开缓存已经不是什么秘密了,所以如果我删除一个作为此类缓存集合的元素的实体,持久化一个应该是一个元素的实体,或者更新一个实体,使其从一个集合移动到另一个集合,我必须手动执行驱逐。

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

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

如何正确同步这些东西?

我尝试在 TransactionSynchronization 的 4 种方法中的每一种中进行驱逐(在相对于事务完成的不同时间点调用),但没有帮助。

4

3 回答 3

3

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

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

于 2009-10-01T20:19:03.840 回答
0

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

于 2009-12-07T03:57:39.017 回答
0

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

还是我错过了什么?为什么你不能简单地保持集合更新?

于 2009-10-01T22:27:35.573 回答