JBoss TreeCache的并发策略配置为二级Hibernate缓存

时间:2011-02-14 21:43:16

标签: hibernate transactions jboss isolation-level jboss-cache

我正在使用JBoss EAP 4.3。

当使用内置的JBoss TreeCache作为Hibernate的二级缓存时,我正在研究并发策略的不同选项。我已经设置好了,我已经通过查看日志来验证缓存是否正常工作,但我不确定实际使用的是什么并发策略以及它的工作方式。

对于每个实体,我可以在@Cache注释中设置以下“使用”值之一:NONEREAD_ONLYNONSTRICT_READ_WRITEREAD_WRITETRANSACTIONAL

另一方面,在我的JBossTreeCache配置文件中,我可以将IsolationLevel设置为整个缓存的以下之一:NONEREAD_UNCOMMITTED,{{1 },READ_COMMITTEDREPEATABLE_READ(或只使用SERIALIZABLE)。

一次查看配置选项时,文档非常清楚,但我想知道当您组合不同选项时会发生什么。

例如,如果您为实体设置OPTIMISTIC,但为@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)设置NONEIsolationLevel,会发生什么?

我还认为JBossTreecache仅支持JBossTreeCacheNONEREAD_ONLY使用,但是您允许将TRANSACTIONAL与它们结合使用?如果你使用例如IsolationLevel

会发生什么

总之,这里应该有5x6种不同的组合,但并非所有组合都有意义。

任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:8)

隔离级别是一个棘手的问题。

  

例如,如果您为实体设置@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL),但为NONE设置IsolationLevelJBossTreecache,会发生什么?

大多数情况下,生产中难以发现的错误...你应该明白,通过使用读写缓存,你实际上已经陷入了分布式交易中的所有“细节”。

好的,关于组合: 当对象不更改时,应使用Hibernate中的只读缓存设置。例如,对于国家字典。缓存并发级别NONE或READ_ONLY应该与它一起使用。

当您的缓存对象发生更改时,应使用非严格读写,但这种情况很少发生,竞争条件的可能性很小。例如,对于时区词典 - 时区可能偶尔出现/消失,但这种情况可能每年发生几次。同样,缓存并发级别NONE或READ_ONLY应该与它一起使用。

现在,更有趣的组合。

Hibernate中的

Transactional缓存不安全,Hibernate假定缓存更新是事务性的,但没有做任何事情来确保它。所以你必须使用一个完整的外部XA(分布式事务)协调器,除非你真的知道你在做什么,否则你真的真的不想要它。最有可能的是,您必须使用完整的EJB3容器来支持XA-manager,尽管可以使用像http://www.atomikos.com/这样的外部事务管理器和普通的servlet + Spring。显然,你需要使用TRANSACTIONAL缓存。

'READ_WRITE`是一个有趣的组合。在这种模式下,Hibernate本身就是一个轻量级的XA协调器,所以它不需要一个完整的外部XA。简要说明它的工作原理:

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

    可能的可重复读取违规。想象一下,我们有事务A(tA)和事务B(tB)同时启动,并且加载对象X,tA然后修改此对象,然后提交tA。在许多使用快照隔离的数据库(Oracle,PostgreSQL,FireBird)中,如果tB再次请求对象X,它应该接收与事务开始时相同的对象状态。但是,READ_WRITE缓存可能违反了这种情况 - 那里没有快照隔离。 Hibernate试图通过在缓存对象上使用时间戳来解决它,但是在计时器分辨率较差的操作系统上(Windows上为15.6ms),可以保证让一些比赛漏掉。

    可能的乐观陈旧对象版本 - 如果您非常不幸在Windows上工作,并且有多个事务提交具有相同的时间戳,则可能会获得过时的对象版本。