【问题标题】:Rollback a @Transactional annotated method回滚 @Transactional 注释的方法
【发布时间】:2012-08-25 01:32:32
【问题描述】:

美好的一天。以下代码:

 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

【问题讨论】:

    标签: java spring hibernate transactions


    【解决方案1】:

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

    你的情况是这样的

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

    查看@Transaction API 和有关rolling back a transaction 的文档。

    如果尽管有文档建议,您仍想进行程序化回滚,那么您需要从TransactionAspectSupport 调用它,正如已经建议的那样。这是来自文档:

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

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

    【讨论】:

    • TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 仍然抛出异常!如何从我的事务方法中返回一些东西?
    • 要使用 TransactionAspectSupport,很遗憾,您必须确保方法/类上没有 @Transactional。这是一个黑客。一种新方法会更干净。
    【解决方案2】:

    使用 TransactionAspectSupport.currentTransactionStatus() 获取 TransactionStatus 将事务管理器添加到您的 bean 尝试在事务管理器中调用 Rollback(DefaultTransactionStatus 状态)。

    参考春天documentation

    强烈建议您使用声明式方法 尽可能回滚。程序化回滚是可用的 你绝对需要它,但它的使用与实现 干净的基于 POJO 的架构。

    【讨论】:

      猜你喜欢
      • 2018-02-23
      • 2020-03-29
      • 2020-01-14
      • 2011-09-07
      • 2019-06-15
      • 1970-01-01
      • 2019-11-18
      • 1970-01-01
      • 2014-12-25
      相关资源
      最近更新 更多