REQUIRES_NEW
正在回滚所有交易:
我有一个标有@Transactional(propagation = REQUIRES_NEW)
的方法
在bean中也有标记为@Transactional(propagation = REQUIRED)
的方法。这些方法从不相互呼唤。它们是从另一个bean单独调用的。但是,当我使用REQUIRES_NEW
标记的方法失败时,它会回滚整个事务,包括标记为REQUIRED
的方法(这是有问题的)。
我的理解是,如果以这种方式考虑,Spring AOP将有机会拦截REQUIRES_NEW
方法并启动新的逻辑事务。
总体思路如下:
@Transactional
class TransactionalBean{
@Transactional(propagation = REQUIRED)
public void methodA(){ //do transactional work }
@Transactional(propagation = REQUIRES_NEW)
public void methodB(){ //do transactional work }
}
然后调用bean看起来像这样:
@Transactional
class CallingBean{
@Autowired
TransactionalBean
public void doWork(){
TransactionalBean.methodA();
TransactionalBean.methodB();
}
}
因此,如果方法A和B成功,一切都很好。但是,当方法B失败时,方法A中完成的工作将被回滚。我的理解是,当methodB()
被调用时,它应该'}被AOP拦截并开始新的交易并暂停其他交易,但它无效。我该如何解决?我使用的是Grails 2.5,Hibernate,JPA
答案 0 :(得分:0)
问题在于CallingBean
被标记为@Transactional
的方式。发生的事情是CallingBean
正在创建一个交易,让我们说t1
。 CallingBean
正在调用两个事务方法methodA和methodB。由于methodA需要事务,因此它将使用现有事务t1
。但是,methodB将创建一个新的交易,因为注释需要一个新的交易,让我们说t2
。当控制退出方法A时,methodA的事务边界不会结束,但是自从事务在调用bean处启动以来,方法B一直保持活动状态。现在事务t2
在方法B中失败了,异常将冒泡到调用bean,事务t1
将失败。
要解决此问题,您可以根据需要执行以下操作之一。
关闭@Transactional
课程中的CallingBean
注释。
//@Transactional
class CallingBean{
...
}
更新注释以使用noRollbackFor
选项
@Transactional(noRollbackFor={WhateverException.class})
class CallingBean{
...
}