Hibernate L2缓存。在集群上使用读写或事务性缓存并发策略?

16
我正在尝试确定我的应用程序(特别是实体更新)应使用哪种缓存并发策略。该应用程序是使用Hibernate开发的Web服务,部署在Amazon EC2集群上,并在Tomcat上运行,因此没有应用服务器。
我知道有非严格读写、读写和事务缓存并发策略可用于可以更新的数据,而且针对Hibernate有成熟、流行、生产就绪的2L缓存提供者:Infinispan、Ehcache、Hazelcast。
但是我不完全理解Hibernate文档中transactionalread-write缓存之间的区别。我认为transactional缓存是群集应用程序的唯一选择,但现在(阅读了一些主题后),我对此不那么确定了。
因此,我的问题是关于read-write缓存的。它是否具有群集安全性?它是否保证数据库和缓存之间的数据同步以及所有连接的服务器之间的同步?或者仅适用于单个服务器应用程序,并且我应始终优先选择transactional缓存?
例如,如果更新实体字段(名字等)的数据库事务失败并已回滚,read-write缓存会丢弃更改还是只会将错误数据(更新的名字)填充到所有其他节点?这需要JTA事务吗? JBoss TreeCache作为第二级Hibernate缓存的并发策略配置主题中提到:
“READ_WRITE是一个有趣的组合。在此模式下,Hibernate本身作为轻量级XA协调器工作,因此不需要完整的外部XA。以下是它的简短描述:
1.在此模式下,Hibernate自己管理事务。所有DB操作必须在事务中进行,自动提交模式不起作用。 在flush()期间(在事务生命周期中可能出现多次,但通常发生在提交之前),Hibernate通过会话搜索已更新/插入/删除的对象。这些对象首先保存到数据库中,然后被锁定并更新到缓存中,以便并发事务既不能更新也不能读取它们。 如果事务被显式地或由于某些错误而回滚,则简单地释放和删除缓存中的锁定对象,以便其他事务可以读取/更新它们。 如果事务成功提交,则简单地释放锁定对象,并允许其他线程读取/写入它们。
还有文档介绍如何在集群环境下使用此功能吗?
似乎事务性缓存在这方面正常工作,但需要JTA环境和独立的事务管理器(例如JBossTM、Atomikos、Bitronix)、XA数据源以及大量的配置更改和测试。我设法部署了它,但仍然遇到一些框架问题。例如,Google Guice IoC不支持JTA事务,我必须将其替换为Spring或将服务移到某个应用服务器并使用EJB。
那么哪种方法更好呢?
提前感谢!
2个回答

20

差异总结

  • NonStrict R/w和R/w都是异步策略,意味着它们在事务完成后更新。
  • Transactional显然是同步的,并在事务内更新。
  • Nonstrict R/w从不锁定实体,因此存在脏读的可能性。
  • Read-Write始终对实体进行软锁定,因此任何同时访问都会被发送到数据库。然而,有很小的几率R/w可能无法产生可重复读隔离。

了解这些策略之间的差异最好的方法是查看它们在插入、更新或删除操作期间的行为。

您可以查看我的帖子这里,其中更详细地描述了差异。欢迎评论。


5

到目前为止,我只看到过在事务性缓存模式下使用集群2LC的情况。这正是Infinispan所做的,事实上,Infinispan迄今为止一直避免实现其他缓存并发模式。为了减轻事务负担,Infinispan通过事务同步与Hibernate集成,而不是XA。


你的意思是说读写缓存策略是集群安全的,但大多数情况下使用事务性吗? - Andy Dufresne
2
不行。读写可以使事情保持一致,但需要进行某种2PC方法或其他方法来保证集群中的一致性。这取决于2LC实现。Infinispan选择跳过读写并使用事务,该事务用于包含所有操作并在集群周围以原子方式运行。 - Galder Zamarreño

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接