回滚带批注@Transactional方法

2022-09-03 05:39:50

日安。下面的代码:

 class A{
     private B b;
    @Transactional
    public SomeResult doSomething(){
        SomeResult res = null;
        try {
          // do something 
        } catch (Exception e) {
            res  = b.saveResult();
        }
        return res ;
    }
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
class B{
  public SomeResult saveResult(){
      // save in db 
  }
}

据我所知,如果方法中存在异常,则不会回滚事务。如何让它滚动?并返回了一些结果doSomething


答案 1

不应以编程方式调用回滚。根据文档的建议,最好的方法是使用声明性方法。为此,您需要注释哪些异常将触发回滚。

在你的情况下,像这样的东西

@Transactional(rollbackFor={MyException.class, AnotherException.class})
public SomeResult doSomething(){
   ...
}

查看@Transaction API 和有关回滚事务的文档。

如果尽管有文档建议,但您希望进行编程回滚,则需要按照已经建议的方式调用它。这是来自文档:TransactionAspectSupport

public void resolvePosition() {
  try {
    // some business logic...
  } catch (NoProductInStockException ex) {
    // trigger rollback programmatically
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  }
}

但是,可能存在体系结构错误。如果你的方法失败,并且需要引发异常,你不应该期望它返回任何内容。也许你对这种方法有太多的责任,应该创建一个只对数据进行建模的单独方法,并在出现问题时引发异常,回滚事务。无论如何,请阅读文档。


答案 2

获取 TransactionStatus using TransactionAspectSupport.currentTransactionStatus() ect transaction Manager to your bean 尝试在事务管理器中调用 Rollback(DefaultTransactionStatus status)。

参考弹簧文档

强烈建议您尽可能使用声明性方法进行回滚。如果您绝对需要编程回滚,则可以使用它,但是与实现基于POJO的干净架构相比,它的使用却不菲。


推荐