2011-08-23 110 views
2

我们在整个应用程序中利用内存中的LRU缓存来处理几种不同的模型。为了避免事务被回滚(比如陈旧的条目)引起的问题,添加了事务性缓存的概念:为每个事务创建一个临时缓存,然后如果条目被回滚或被复制到主如果提交该模型缓存。什么时候应该调用Transaction.delistResource()?

要做到这一点,高速缓存实现XAResource并覆盖commit()rollback()方法。每当新的Transaction想要访问一些不在主缓存中的数据时,就会创建事务缓存并将其传递到enlistResource()

的问题是,我试图在commit()rollback()方法,这是抛出IllegalStateException中调用delistResource()的缓存实例,称该交易已经被标记为回滚(或提交)。所以我想知道......是不是而不是将缓存作为资源去除(换句话说,它已经作为回滚或提交过程的一部分被除牌),还是流程中还有另一点叫做?

回答

1

它不是调用delistResource的XAResource方法,它是应用程序服务器的Transaction实现。如果你想要一个资源被除名,那么获取这个事务并调用它,除非需要,它会在你的资源上调用end()。事务管理器同样将隐式调用end()作为终止处理的一部分,所以你不需要在提交或回滚时手动执行。在多个事务上下文中使用相同的资源实例时,您需要处理除名的唯一情况。例如

 

    Cache c = getCache(); 
    c.makeUpdate(); // no transaction running, should auto commit. 
    tx.begin(); // start tx A 
    c.makeUpdate(); // transactional within A 
    tx.suspend(); 
    tx.begin(); // start tx B 
    c.makeUpdate(); // transactional within B 
    tx.commit(); //end B 
    tx.resume(A); 
    tx.commit(); // end A 

根据您的缓存实现可能需要退市的暂停和恢复再争取,但不提交或回滚。或者,您可以检查每个makeUpdate()调用的事务上下文,而不是依赖enlist/delist调用的顺序来更新资源实例所持有的有效tx上下文。

由于程序XA规范和面向对象的JTA规范或多或少的映射不佳,这个东西很难。坦率地说,你可能最好把它交给专家。例如,JBoss Infinispan提供了一个开源事务缓存,为您提供所有这些服务,并提供大量其他功能。

相关问题