使用try catch块时,Spring @Transactional注释

Ked*_*ikh 24 spring spring-mvc

如果我们在使用@Transactional注释注释的方法中捕获异常,那么如果发生任何异常,它是否会回滚?

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

Ank*_*hal 24

例如

class A{

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

        }
        return res ;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果在该方法的例外doStuff事务不会回滚.

To rollback the exception programmatically,我们可以做类似下面的事情.

陈述性方法

@Transactional(rollbackFor={MyException1.class, MyException2.class, ....})
public Result doStuff(){
   ...
}
Run Code Online (Sandbox Code Playgroud)

您需要从中调用它的程序化回滚TransactionAspectSupport.

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

You are strongly encouraged to use the `declarative approach` to `rollback` if at all possible. 
`Programmatic rollback` is available should only be used if you absolutely need it.
Run Code Online (Sandbox Code Playgroud)

  • @ankur-singhal,我不明白为什么我们需要`@Transactional(rollbackFor={MyException1.class, MyException2.class, ....})`?默认的 `rollbackFor` 是 `Throwable`,应该已经覆盖了吧? (2认同)
  • 这并非总是如此。如果插入或更新失败(即使被 try/catch 包围),这里仍然会发生回滚。这是因为当 Spring Boot 检测到数据库错误时,无论是否捕获异常,它都会将事务标记为“rollBackOnly” (2认同)