REQUIRES_NEW
正在回滚所有事务:
我有一个标记为@Transactional(propagation = REQUIRES_NEW)
的方法
在还具有标记为@Transactional(propagation = REQUIRED)
的方法的bean中。这些方法从不相互调用。它们分别从另一个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
最佳答案
问题在于CallingBean
被标记为@Transactional
的方式。发生的是CallingBean
正在创建事务,比方说t1
。 CallingBean
正在调用两个事务处理方法methodA和methodB。由于methodA需要事务,因此它将利用现有事务t1
。但是,methodB将创建一个新事务,因为注释需要一个新事务,比方说t2
。当控件退出方法A时,方法A的事务边界不会结束,但是直到事务B在调用Bean处开始执行之后,方法A的事务边界才保持有效。现在,事务t2
在methodB中失败了,该异常将冒泡到调用方,事务t1
将失败。
为了解决此问题,您可以根据需要执行以下操作之一。
关闭@Transactional
类中的CallingBean
批注。
//@Transactional
class CallingBean{
...
}
更新注释以使用
noRollbackFor
选项@Transactional(noRollbackFor={WhateverException.class})
class CallingBean{
...
}
关于spring - Grails/Spring REQUIRES_NEW回滚外部事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44635880/