2011-02-14 70 views
4

我正在使用JBoss EAP 4.3。JBoss TreeCache的并发策略配置作为第二级休眠缓存

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

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

在另一方面,我JBossTreeCache配置文件我可以设置IsolationLevel为整个高速缓存执行下列操作之一:NONEREAD_UNCOMMITTEDREAD_COMMITTEDREPEATABLE_READSERIALIZABLE(或者只是使用OPTIMISTIC)。

在逐个查看配置选项时,文档非常清晰,但我不知道将不同选项合并时会发生什么情况。

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

我也相信,JBossTreeCache只支持NONEREAD_ONLYTRANSACTIONAL使用,但什么IsolationLevel是你允许他们结合?如果你使用例如NONSTRICT_READ_WRITE会发生什么?

产品总数应该有像5x6至不同的组合在这里,但不是所有的人都有道理..

能anyoone帮我整理了这一点?

回答

8

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

例如,如果您为实体集@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)但对于JBossTreecache配置NONEIsolationLevel,会发生什么?

大多数情况下,在生产中很难找到错误......您应该明白,通过使用读写缓存,您基本上可以在分布式事务中使自己的所有“细节”变得沉闷。

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

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

现在,更有趣的组合。

Transactional Hibernate中的缓存是不安全的,Hibernate假定缓存更新是事务性的,但是无法确保它。所以你必须使用一个全面的外部XA(分布式事务)协调器,除非你真的知道自己在做什么,否则你确实真的不需要它。很可能,您必须使用完整的EJB3容器来支持XA-manager,尽管可以使用外部事务管理器(如http://www.atomikos.com/)和纯servlet + Spring。显然,你需要使用TRANSACTIONAL缓存。

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

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

这里有几个细微之处的:

可能重复读违反。假设我们有事务A(tA)和事务B(tB)同时启动,并且加载对象X和tA然后修改这个对象,然后提交tA。在许多使用快照隔离的数据库(Oracle,PostgreSQL,FireBird)中,如果tB再次请求对象X,它应该接收与事务开始时相同的对象状态。但是,READ_WRITE缓存可能会违反此条件 - 此处没有快照隔离。 Hibernate尝试通过在缓存对象上使用时间戳,但在定时器分辨率较差的操作系统(Windows上15.6ms)上使用时间戳,它可以保证让一些种族溜走。

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

+0

感谢您付出努力回答我的问题。然而,有几件事对我来说并不清楚:你写道“NONE或READ_ONLY应该与它一起使用”。你真的指的是JBossTreeCache吗?我在JBossTreeCache中找不到READ_ONLY IsolationLevel。我还认为JBossTreeCache不支持NONSTRICT_READ_WRITE和READ_WRITE Hibernate的用法。你能评论一下吗? – Steve 2011-02-23 21:29:09