Medium java spring

An exception was thrown but the transaction still committed. Why?

The 30 second answer

There are three usual causes. By default Spring rolls back only on unchecked exceptions and errors, so a checked exception still commits unless I set rollbackFor. Second, the exception was caught inside the method and never rethrown. Third, self-invocation: calling a transactional method from the same class skips the proxy, so no transaction is started for that call.

Three common causes. One: by default Spring rolls back only on unchecked exceptions (RuntimeException and Error), not checked ones; fix with rollbackFor = Exception.class. Two: the exception was caught inside the method and not rethrown. Three: self-invocation; calling a @Transactional method from the same class skips the proxy, so no transaction starts on that call. Follow-up: How do you fix self-invocation? (Move the method to another bean, or inject the proxy; the docs suggest AspectJ mode as an alternative.)

Sources (2)
  1. Spring: Rolling back a declarative transaction
  2. Spring: Using @Transactional (proxy and self-invocation)