即使在非事务方法或控制器中捕获异常,Spring事务方法也会获得回滚

时间:2016-11-15 07:23:34

标签: spring hibernate transactional

我在非事务方法中调用try-catch块中的两个事务方法。发生异常时,我能够捕获异常并将其记录下来。第一个事务方法不会回滚,但最后一个事务方法会回滚。这种行为是我目前在春季交易管理中所理解的。

public void grab(){
    try{
        requestManager.updateRequest();
        requestManager.saveTicket()
    }catch (DataIntegrityViolationException dive) {
       if (dive.getCause() instanceof ConstraintViolationException) {
           LOGGER.error("ConstraintViolationException",dive);
       }
    }
}

在上面的代码中,ConstraintViolationException发生在saveTicket()方法中,并且saveTicket()内的dao甚至在捕获异常之前已经回滚了它的事务(这是我所知道的),并且第一个没有回滚因为它在另一个交易中。(这是我已经知道的行为)。

当我使用另一个调用那两个预览方法(updateRequest()和saveTicket())的事务方法时,我很困惑,即使捕获异常,当saveTicket()方法发生ConstraintViolationException时,甚至还会回滚updateRequest()方法。这是我的代码

 public void grab(){
    try{
        requestManager.grabRequest();
    }catch (DataIntegrityViolationException dive) {
       if (dive.getCause() instanceof ConstraintViolationException) {
           LOGGER.error("ConstraintViolationException",dive);
       }
    }
 }

我所知道的是,这两个方法将在grabRequest()方法中加入相同的事务,但我的问题是,为什么即使我捕获异常,事务也会回滚?这是否意味着即使在我捕获异常之前,spring使用的代理已经回滚了事务?

1 个答案:

答案 0 :(得分:0)

  

这是否意味着Spring捕获的代理甚至在我捕获异常之前就已经回滚了事务?

是的,在JPA / Spring注释中,您可以指定一个例外列表,您的事务管理器必须回滚或不能在@Transactional

中回滚
  

在默认配置中,Spring Framework的事务基础结构代码仅在运行时未经检查的异常情况下标记用于回滚的事务;也就是说,抛出的异常是RuntimeException的实例或子类。 (错误也将 - 默认情况下 - 导致回滚)。从事务方法抛出的已检查异常不会导致在默认配置中回滚。

来自http://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html

对于JPA,rollbackOndontRollbackOn