休眠 L2 缓存。集群上的读写或事务缓存并发策略?

我正在尝试确定我应该为我的应用程序使用哪种缓存并发策略(特别是对于实体更新)。该应用程序是使用Hibernate开发的Web服务,部署在Amazon EC2集群上,并在Tomcat上运行,因此那里没有应用程序服务器。

我知道有可以更新的数据的非限制读写\读写事务缓存并发策略,并且有成熟,流行,生产就绪的Hibernate缓存提供程序:Infinispan,Ehcache,Hazelcast。

但我不完全理解Hibernate文档中的事务缓存和读写缓存之间的区别。我认为事务缓存是集群应用程序的唯一选择,但现在(在阅读了一些主题之后),我不太确定这一点。

所以我的问题是关于读写缓存的。它是否是群集安全的?它是否保证数据库和缓存之间的数据同步以及所有连接的服务器之间的同步?或者它只适用于单服务器应用程序,我应该总是更喜欢事务性缓存?

例如,如果正在更新实体字段(名字等)的数据库事务失败并且已回滚,读写缓存是会丢弃更改,还是只会将错误数据(更新后的名字)填充到所有其他节点?是否需要 JTA 事务?

JBoss TreeCache 作为 2nd 级休眠缓存主题的并发策略配置说:

“READ_WRITE”是一个有趣的组合。在此模式下,休眠本身可用作轻量级 XA 协调器,因此不需要完整的外部 XA。其工作原理的简短描述:

  1. 在此模式下,休眠管理事务本身。所有数据库操作都必须位于事务内,自动提交模式将不起作用。
  2. 在 flush() 期间(在事务生存期内可能会多次出现,但通常发生在提交之前),Hibernate 会通过会话并搜索更新/插入/删除的对象。然后,这些对象首先保存到数据库中,然后在缓存中锁定和更新,以便并发事务既不能更新也不能读取它们。
  3. 如果随后回滚事务(显式或由于某些错误),则锁定的对象将被释放并从缓存中逐出,以便其他事务可以读取/更新它们。
  4. 如果事务提交成功,则锁定的对象将被释放,其他线程可以读/写它们。

是否有一些文档说明如何在群集环境中工作?

似乎事务缓存可以正常工作,但需要具有独立事务管理器(例如JBossTM,Atomikos,Bitronix),XA数据源以及大量配置更改和测试的JTA环境。我设法部署了这个,但我的框架仍然有一些问题。例如,Google Guice IoC不支持JTA事务,我必须用Spring替换它,或者将服务移动到某个应用程序服务器并使用EJB。

那么哪种方式更好呢?

提前致谢!


答案 1

差异摘要

  • 非限制 R/w 和 R/w 都是异步策略,这意味着它们在事务完成后更新。
  • 事务性显然是同步的,并在事务中更新。
  • 非限制 R/w 永远不会锁定实体,因此总是有可能进行脏读。
  • 读写始终软锁定实体,因此任何同时访问都会发送到数据库。但是,R/w 很可能不会产生可重复读取隔离。

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

您可以在此处查看我的帖子,其中更详细地描述了差异。随时发表评论。


答案 2

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