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

时间:2014-09-09 07:25:37

标签: spring spring-mvc

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

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

4 个答案:

答案 0 :(得分:19)

例如

class A{

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

        }
        return res ;
    }
}

如果方法doStuff中存在例外情况,则交易不会回滚。

To rollback the exception programmatically,我们可以执行以下操作。

陈述性方法

@Transactional(rollbackFor={MyException1.class, MyException2.class, ....})
public Result doStuff(){
   ...
}

程序化回滚 你需要从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.

答案 1 :(得分:2)

您希望阅读this

集成交易管理。您可以通过@Transactional注释或通过在XML配置文件中显式配置事务AOP建议,使用声明性,面向方面编程(AOP)样式方法拦截器来包装ORM代码。在这两种情况下,都会为您处理事务语义和异常处理(回滚等)。如下所述,在资源和事务管理中,您还可以交换各种事务管理器,而不会影响与ORM相关的代码。例如,您可以使用两种方案中可用的相同完整服务(例如声明性事务)在本地事务和JTA之间进行交换。此外,与JDBC相关的代码可以与您用于执行ORM的代码进行事务性完全集成。这对于不适合ORM的数据访问很有用,例如批处理和BLOB流,它仍然需要与ORM操作共享常见事务。

答案 2 :(得分:2)

来自春季参考文档

Spring建议您只注释具体类(以及具体类的方法) 使用@Transactional注释,而不是注释接口。你当然可以 将@Transactional注释放在接口(或接口方法)上,但这可行 只有在您使用基于接口的代理时才会如此期望。 Java的事实 如果您使用基于类的代理,那么注释不会从接口继承 (proxy-target-class =" true")或基于编织的方面(mode =" aspectj"),然后 代理和编织基础设施无法识别交易设置 对象不会被包装在事务代理中,这将是非常糟糕的。

在代理模式(默认设置)下,只有通过代理进入的外部方法调用 截获。这意味着自调用实际上是目标对象调用中的一个方法 目标对象的另一种方法,即使是在运行时也不会导致实际的事务 调用的方法用@Transactional标记。

然后使用@Transaction,默认行为是任何RuntimeException都会触发回滚,而任何已检查的Exception都不会。然后,对于已检查的Exception Throwable

,您的事务将回滚所有RuntimeException

答案 3 :(得分:-1)

你已经在@Transactional注释中提到了属性:rollbackFor = Throwable.class。

因此,对于任何类型的异常事务都将被回滚。