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

Spring transactional method gets rollback even if exception is catched in non-transactional method or in controller

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

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 使用的代理甚至在我捕捉到异常之前就已经回滚了事务?

Does this mean that the proxy that spring uses already rolled back the transaction even before i catch the exception?

是的,在 JPA/Spring 注释中,您可以在 @Transactional

中指定事务管理器必须回滚或不得回滚的异常列表

In its default configuration, the Spring Framework’s transaction infrastructure code only marks a transaction for rollback in the case of runtime, unchecked exceptions; that is, when the thrown exception is an instance or subclass of RuntimeException. ( Errors will also - by default - result in a rollback). Checked exceptions that are thrown from a transactional method do not result in rollback in the default configuration.

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

对于 JPA,它是 rollbackOndontRollbackOn