Search code examples
springhibernatetransactional

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


I am calling two transactional methods inside try-catch block in a non-transactional method. When exception occurs, i am able to catch the exception and logs it. The first transaction method does not get roll back but the last one does. This behavior is what i currently understand in spring transaction management.

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

In the above code, the ConstraintViolationException occurs inside saveTicket() method and the dao inside saveTicket() already rolled back its transaction even before catching the exception(This is what i know), and the first one does not get rolled back because it is in another transaction.(This is the behavior i already know).

I got confused when i used another transactional method which calls those two previews method(updateRequest() and saveTicket()) which gets rolled back even the updateRequest() method when ConstraintViolationException occurs in saveTicket() method even if catching the exception. Here is my code

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

What i know is, the two methods will join same transaction inside grabRequest() method, But my question is, why do the transaction gets rolled back even if i am catching the exception? Does this mean that the proxy that spring uses already rolled back the transaction even before i catch the exception?


Solution

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

    Yes, in JPA/Spring annotation you can specify a list of Exceptions which your transaction manager must rollback or mustn't rollback in the @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.

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

    For JPA it's rollbackOn and dontRollbackOn