spring - Grails/Spring REQUIRES_NEW回滚外部事务

标签 spring grails

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正在创建事务,比方说t1CallingBean正在调用两个事务处理方法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/

相关文章:

mysql - 如何捕获 Grails 中的约束(索引)违规?

Grails spock-如何模拟/ stub 类的特定方法

grails - Grails拒绝值[null]

java - JAXB Marshall 泛型类型的 Map 结构

java - 使用 maven 在 tomcat 中使用共享父 spring 上下文处理多 war 设置

grails - Grails 2.2.1无法识别从BuildConfig.groovy安装了 “release”插件

grails - Config.groovy属性的InList约束值

java - 尝试使用 RestTemplate 获取对象列表时响应正文为空

java - 事件监听器 hibernate 5

java - 速度 2.0 : NoClassDefFoundError: org/apache/velocity/runtime/log/CommonsLogLogChute