16

再会。以下代码:

 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则不会回滚事务。以及如何让它滚动?并返回 SomeResult

4

2 回答 2

22

您不应该以编程方式调用 Rollback。正如文档所推荐的,最好的方法是使用声明性方法。为此,您需要注释哪些异常将触发回滚。

在你的情况下,像这样

@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();
  }
}

虽然可能存在架构错误。如果你的方法失败并且你需要抛出一个异常,你不应该期望它返回任何东西。也许你给这个方法太多的责任,应该创建一个单独的模型数据,如果出现问题,抛出异常,回滚事务。无论如何,请阅读文档。

于 2012-08-30T10:53:59.407 回答
2

使用 TransactionAspectSupport.currentTransactionStatus() 等事务管理器获取 TransactionStatus 到您的 bean 尝试在事务管理器中调用 Rollback(DefaultTransactionStatus status)。

参考弹簧文档

如果可能,强烈建议您使用声明性方法进行回滚。如果您绝对需要,可以使用程序化回滚,但它的使用与实现干净的基于 POJO 的架构背道而驰。

于 2012-08-30T10:39:50.190 回答