11

When a method is annotated with @Transactional and there is an runtime exception, spring eats the exception and throws:

org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only

How do I avoid this "general" exception and propagate the original exception, but keeping the rollback?

Thanks.

Ken Chan
  • 84,777
  • 26
  • 143
  • 172
Thiago Sayão
  • 2,197
  • 3
  • 27
  • 41

1 Answers1

22

org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only

It mostly happens if you have an outer @Transactional method calls an inner @Transactional method. When the inner method throws an exception , but the outer method catches this exception and return normally, Spring is confused and don't know if it should rollback or commit the transaction since both methods contradict with each other. (Inner method says it wants to rollback but the outer method says it want to commit)

So , check if there are any outer @Transactional methods that catch the exception. If yes , re-throw that exception from the outer method such that the whole transaction will rollback.

Ken Chan
  • 84,777
  • 26
  • 143
  • 172
  • I am catching the Exception in the outer class which just says "UnexpectedRollbackException", but I want to know why the inner class is throwing an exception. how to make the inner class not rollback? – Sudo Pehpeh Oct 29 '21 at 05:49
  • You can configure `noRollbackFor` of the `@Transactional` of the inner method to define which exception that you do not want to rollback – Ken Chan Nov 11 '21 at 15:00
  • 2
    @KenChan How to do this? I tried adding the `rollbackFor = Exception.class` in the inner or outer method, but none seem to work. I just want to do the rollback and ignore that exception. – Dhana D. May 10 '22 at 10:19