Search code examples
javaspringtransactions

Spring Transaction : rollbackfor and norollbackfor both defined


Here is the problem I got in an application I have to maintain:

I have a first class with the annotation @Transactional(rollbackFor = CustomExceptionA.class) Then in the following code I call a method of @Transactional(noRollbackFor = CustomExceptionB.class) NB : CustomExceptionA or CustomExceptionB have only one common ancestor which is Exception.

And of course, when I execute the code an exception is raised which is neither of type CustomExceptionA or CustomExceptionB nor does it subclasses them.

So the question is simple:
What happens to the transaction in that case? Does it commit? Does it rollback? Does it hold on an unfinished state waiting for the application to do something (which is actually an answer that might explain some ugly things seen in this application)? and moreover: why?


Solution

  • Spring Framework's transaction infrastructure code will, by default, only mark 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 will not result in the transaction being rolled back.

    Why? That makes a perfect sense: checked exceptions are mandatory for handling or throwing out, so if you're throwing the checked exception out of the transactional method, then framework supposes you know what you're doing. In case of unchecled exceptionit's likely to be a bug, or exception handling flaw, so transaction is rolled back to avoid data corruption.