Database Concurrency & Scaling interview question · Most asked

A Spring @Transactional method threw an exception but the data was still saved. What are the likely causes?

Summary

Either the method wasn't actually transactional (self-invocation bypasses the proxy, or the method isn't public on a Spring bean) or the exception was a checked exception, which commits by default. Also check for swallowed exceptions and REQUIRES_NEW calls.

Longer Answer

  • Self-invocation: this.placeOrder() from the same class doesn't go through the proxy — no transaction at all.
  • Checked exceptions: Spring rolls back only on RuntimeException/Error unless rollbackFor is set.
  • Swallowed exceptions: catching the exception inside the transactional method means the interceptor never sees it.
  • Propagation.REQUIRES_NEW inner calls commit independently of the outer transaction.
  • Different transaction managers / datasources: the write went through a connection not bound to the transaction.

Fix by moving the method to another bean (or calling through the proxy), using rollbackFor = Exception.class where appropriate, rethrowing, and testing the failure path.

Key Points

  • Proxy-based: self-calls skip it
  • Checked exceptions commit by default
  • Don't swallow exceptions
  • Beware REQUIRES_NEW

Deep dive: Framework Transaction Pitfalls

More most-asked Database Concurrency & Scaling questions

← All Database Concurrency & Scaling questions