Interview Prep Zoneby CuriouserLabs

Question 2 of 5 · staff level

Explain transaction propagation. REQUIRED vs REQUIRES_NEW vs NESTED — and when does each matter?

🎤 Say this first

Propagation answers: a transaction may already exist — what now? REQUIRED (default) joins it or starts one — one shared fate; an inner failure marks the whole TX rollback-only, even if you catch the exception. REQUIRES_NEW suspends the outer TX and runs an independent one — commits/rolls back alone (audit logs, payment records), but holds a second connection. NESTED takes a JDBC savepoint in the same TX — inner work can roll back alone, but commits only with the outer. Others: SUPPORTS/NOT_SUPPORTED/MANDATORY/NEVER for edge contracts.

The full picture

🎬 Transaction propagation: REQUIRED vs REQUIRES_NEW

1 / 5
placeOrder()@Transactional REQUIREDchargeCard()REQUIRED → joinscallsTX1 (one physical transaction)Propagation answers one question: “a transaction already exists — join it, suspend it, or fail?”

placeOrder() is @Transactional (default propagation = REQUIRED). No transaction exists yet, so the proxy starts TX1 and binds it to the current thread.

One shared fate vs suspended-outer/independent-inner — including the rollback-only trap.
PropagationExisting TX?No TX?Use when
REQUIREDjoin itstart onedefault — one business operation, one fate
REQUIRES_NEWsuspend, start newstart newmust-survive records: audit, outbox-ish writes, payment attempts
NESTEDsavepoint in same TXstart onepartial rollback of a sub-step, same commit point (JDBC only)
MANDATORYjointhrow'caller must own the TX' contracts
NOT_SUPPORTEDsuspend, run withoutrun withoutlong reads/reporting inside transactional flows

🔄 Likely follow-up questions

  • Why does NESTED not work with JPA/Hibernate?
  • Construct a pool-exhaustion deadlock from REQUIRES_NEW under load.
  • How do you test propagation behavior meaningfully?