使用 try catch 块时的 Spring @Transactional 注解

新手上路,请多包涵

如果我们在用 @Transactional 注解注解的方法中捕获异常,出现异常会回滚吗?

 @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=Throwable.class)
public void yearEndProcess() {
    try {
        // try block
    } catch (Throwable throwable) {
        // catch block
    }
}

原文由 Kedar Parikh 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

例如

class A{

    @Transactional
    public Result doStuff(){
        Result res = null;
        try {
          // do stuff
        } catch (Exception e) {

        }
        return res ;
    }
}

如果方法中存在异常 doStuff 事务不会回滚。

To rollback the exception programmatically ,我们可以做如下的事情。

声明式方法

@Transactional(rollbackFor={MyException1.class, MyException2.class, ....})
public Result doStuff(){
   ...
}

编程回滚

您需要从 TransactionAspectSupport 调用它。

     public Result doStuff(){
      try {
        // business logic...
      } catch (Exception ex) {
        // trigger rollback programmatically
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      }
    }

强烈建议您尽可能使用 declarative approachrollbackProgrammatic rollback 仅在绝对需要时才可用。

原文由 Ankur Singhal 发布,翻译遵循 CC BY-SA 4.0 许可协议

来自 spring 参考文档

Spring 建议您只使用 @Transactional 注解来注解具体类(和具体类的方法),而不是注解接口。您当然可以将 @Transactional 注释放置在接口(或接口方法)上,但这仅在您使用基于接口的代理时才像您期望的那样起作用。 Java 注释不是从接口继承的事实意味着如果您使用基于类的代理(proxy-target-class=“true”)或基于编织的方面(mode=“aspectj”),那么事务设置是不被代理和编织基础设施识别,并且对象不会被包装在事务代理中,这肯定是不好的。

在代理模式(默认)下,只有通过代理传入的外部方法调用才会被拦截。这意味着自调用实际上是目标对象中的一个方法调用目标对象的另一个方法,即使被调用的方法标有@Transactional,也不会在运行时导致实际事务。

然后使用 @Transaction 默认行为是任何 RuntimeException 触发回滚,而任何检查的 Exception 都不会。然后您的事务回滚所有 RuntimeException 和检查的 Exception Throwable

原文由 Skizzo 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题