java 回滚一个@Transactional 注释的方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12194891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:58:59  来源:igfitidea点击:

Rollback a @Transactional annotated method

javaspringhibernatetransactions

提问by yaroslavTir

Good day. The following code:

再会。以下代码:

 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 
  }
}

As I understand, if there is an exception in the method doSomethingthe transaction isn't rolled back. And how to make that it rolled? and returned SomeResult

据我了解,如果方法中有异常,doSomething则事务不会回滚。以及如何使它滚动?并返回 SomeResult

回答by Caio Cunha

You shouldn't call Rollback programmatically. The best way, as recommended by the docs, is to use declarative approach. To do so, you need to annotate which exceptions will trigger a Rollback.

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

In your case, something like this

在你的情况下,像这样

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

Take a look at the @Transaction APIand the docs about rolling back a transaction.

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

If, despite the docs recommendation, you want to make a programmatic rollback, then you need to call it from TransactionAspectSupportas already suggested. This is from the docs:

如果不顾文档的建议,您想要进行编程回滚,那么您需要TransactionAspectSupport按照已经建议的方式调用它。这是来自文档:

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

There may be a architecture mistake though. If your method fails and you need to throw an exception, you shouldn't expect it to return anything. Maybe you're giving too much responsibilities to this method and should create a separated one that only model data, and throws an exception if something goes wrong, rolling back the transaction. Anyway, read the docs.

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

回答by Jigar Parekh

get TransactionStatus using TransactionAspectSupport.currentTransactionStatus() ect transaction manager to your bean try to invoke Rollback(DefaultTransactionStatus status) in transaction manager.

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

refer to spring documentation

参考spring文档

You are strongly encouraged to use the declarative approach to rollback if at all possible. Programmatic rollback is available should you absolutely need it, but its usage flies in the face of achieving a clean POJO-based architecture.

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