skip to content

Transaction Management

Spring's transaction abstraction end to end: the manager SPI, the declarative @Transactional attributes, propagation behaviours, programmatic transactions, and the reactive or distributed cases. Data-integrity questions in backend interviews almost always land here.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

150 · 6 sections

What is DataSourceTransactionManager and when do you use it?

level: juniorimportance: must knowfreq 70%
basics
~10 s

It is Spring's PlatformTransactionManager for a single JDBC DataSource. It opens a database Connection, turns off auto-commit, and commits or rolls back when the transaction ends. Use it with JdbcTemplate or MyBatis.

open as a page

What is JpaTransactionManager and when do you use it?

level: juniorimportance: must knowfreq 70%
basics
~10 s

JpaTransactionManager is Spring's PlatformTransactionManager for JPA. It opens an EntityManager, starts a transaction on it, and commits or rolls back when a @Transactional method finishes. Use it when your app persists data through JPA/Hibernate.

open as a page

You have two PlatformTransactionManager beans in your Spring context. How does @Transactional know which one to use, and how do you point a method at a specific one?

level: juniorimportance: must knowfreq 55%
basics
~10 s

By default Spring needs one clear choice. To pick a specific manager, pass its bean name as a qualifier: @Transactional("orderTxManager") or @Transactional(transactionManager = "orderTxManager").

open as a page

What is the PlatformTransactionManager interface in Spring, and what three methods does it define?

level: juniorimportance: must knowfreq 60%
basics
~10 s

It is Spring's central interface for managing transactions. It defines three methods: getTransaction (start/join a transaction), commit (make changes permanent), and rollback (undo changes).

open as a page

What is ReactiveTransactionManager and how does it differ from PlatformTransactionManager?

level: juniorimportance: must knowfreq 55%
basics
~10 s

ReactiveTransactionManager runs transactions for non-blocking code, returning Mono results instead of blocking. PlatformTransactionManager is the classic blocking one for imperative code (JDBC/JPA). You pick the one matching your stack.

open as a page

What does @Transactional do, and what happens around a method annotated with it?

level: juniorimportance: must knowfreq 90%
basics
~10 s

@Transactional tells Spring to run the method inside a database transaction: Spring starts a transaction before the method, commits if it returns normally, and rolls back if it throws a runtime exception.

open as a page

What does the `isolation` attribute of `@Transactional` control, and what are the five values Spring offers?

level: juniorimportance: must knowfreq 62%
basics
~10 s

It sets how much one transaction is shielded from data other in-flight transactions are changing. Spring's Isolation enum offers DEFAULT, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, and SERIALIZABLE — higher levels give more consistency but less concurrency.

open as a page

What does @Transactional(readOnly = true) do in Spring?

level: juniorimportance: must knowfreq 70%
basics
~20 s

It marks a transaction as read-only: a hint that the method only reads data. Spring passes this to Hibernate and the JDBC driver so they can optimize, for example by skipping dirty-checking and the automatic flush.

open as a page

By default, which exceptions cause a Spring @Transactional method to roll back, and which let it commit?

level: juniorimportance: must knowfreq 80%
basics
~10 s

By default Spring rolls back on unchecked exceptions (RuntimeException) and Error. It commits on checked exceptions (any Exception that isn't a RuntimeException). You must opt in to roll back on checked exceptions.

open as a page

What does the timeout attribute of @Transactional do, and in what unit do you specify it?

level: juniorimportance: must knowfreq 40%
basics
~10 s

@Transactional(timeout = N) limits how long the transaction may run to N seconds. If it exceeds that, Spring aborts it and rolls back, throwing a TransactionTimedOutException. The unit is always seconds.

open as a page

What does Propagation.NOT_SUPPORTED do in Spring's declarative transaction management?

level: juniorimportance: must knowfreq 45%
basics
~10 s

NOT_SUPPORTED runs the method without a transaction. If a transaction is already active, Spring pauses (suspends) it, runs the method non-transactionally, then resumes the paused transaction afterward.

open as a page

What is Propagation.REQUIRED in Spring's @Transactional, and how does it decide whether to start a new transaction?

level: juniorimportance: must knowfreq 80%
basics
~10 s

REQUIRED is the default propagation. If a transaction is already running, the method joins it; if none exists, Spring starts a new one. So the code always runs inside exactly one transaction.

open as a page

What does Propagation.REQUIRES_NEW do in Spring's @Transactional?

level: juniorimportance: must knowfreq 72%
basics
~10 s

REQUIRES_NEW always starts a brand-new, independent transaction. If a transaction is already running, Spring pauses (suspends) it, runs the new one on its own database connection, then resumes the old one.

open as a page

In Spring, what do the SUPPORTS, MANDATORY, and NEVER transaction propagation modes each do?

level: juniorimportance: must knowfreq 70%
basics
~20 s

SUPPORTS joins an existing transaction if one is active, otherwise runs without one. MANDATORY requires an active transaction and throws if none exists. NEVER requires that no transaction is active and throws if one exists.

open as a page

Compare Propagation.NESTED and Propagation.REQUIRES_NEW. When would you choose one over the other?

level: middleimportance: must knowfreq 60%
basics
~20 s

REQUIRES_NEW opens a separate transaction that commits on its own, surviving an outer rollback. NESTED stays inside one transaction using a savepoint; nested work is lost if the outer rolls back. Use REQUIRES_NEW for truly independent commits, NESTED for partial rollback within one unit.

open as a page

What is TransactionalOperator and why can't you just use @Transactional / a ThreadLocal-based transaction in reactive (WebFlux/R2DBC) code?

level: juniorimportance: must knowfreq 70%
basics
~20 s

TransactionalOperator is a helper that wraps a Mono or Flux in a transaction. Reactive code hops threads, so the classic ThreadLocal transaction doesn't work; the operator carries the transaction in the Reactor Context instead. It commits on success, rolls back on error.

open as a page

What is TransactionStatus in Spring's programmatic transaction API, and what does setRollbackOnly() do?

level: juniorimportance: must knowfreq 55%
basics
~10 s

TransactionStatus is a handle to the current transaction that PlatformTransactionManager gives you. Calling setRollbackOnly() marks the transaction so it can only roll back — commit will not succeed.

open as a page

What is Spring's TransactionTemplate and when would you reach for it instead of @Transactional?

level: juniorimportance: must knowfreq 55%
basics
~20 s

TransactionTemplate runs a block of code inside a database transaction programmatically. You call execute() and pass a callback; Spring starts a transaction, runs your code, then commits or rolls back. Use it when you need transaction control in code rather than the @Transactional annotation.

open as a page

Walk through the correct try/catch pattern for a manager-driven transaction. What goes wrong if the catch block is written incorrectly?

level: middleimportance: must knowfreq 45%
basics
~10 s

Get a TransactionStatus, do the work, and commit inside try. In catch, call rollback(status) and rethrow. If you forget rollback, a failed transaction stays open and the connection may leak or auto-commit dirty data.

open as a page

With operator.transactional(mono/flux), exactly which reactive signal triggers a commit and which triggers a rollback? What happens on cancellation?

level: middleimportance: must knowfreq 60%
basics
~10 s

It commits when the wrapped publisher completes normally (onComplete). It rolls back if the publisher emits an error (onError). If the subscription is cancelled before completing, it also rolls back.

open as a page

If you call an @Async method from within a @Transactional method, does the async code run inside the same transaction?

level: juniorimportance: must knowfreq 35%
basics
~20 s

No. @Async runs the method on a different thread, and Spring ties a transaction to the thread that started it. So the async code runs in its own separate transaction (or none), not the caller's.

open as a page

In a @Transactional Spring method, what happens to the transaction if a checked exception is thrown out of the method?

level: juniorimportance: must knowfreq 70%
basics
~10 s

By default Spring COMMITS the transaction. Spring only rolls back automatically on unchecked exceptions (RuntimeException and Error). A checked exception like IOException does not trigger a rollback unless you configure it.

open as a page

What is a LazyInitializationException, and why does it commonly appear when a controller serializes an entity returned by a service?

level: juniorimportance: must knowfreq 78%
basics
~10 s

It's a Hibernate error thrown when you access a lazily-loaded field (like a list of orders) after the database session has already closed. The service's transaction ended, so Hibernate can't fetch the data anymore.

open as a page

Why is @Transactional silently ignored when you put it on a private method?

level: juniorimportance: must knowfreq 70%
basics
~20 s

Spring adds transactions with a proxy — a wrapper object around your bean. The proxy can only intercept public methods it can override. Private methods can't be overridden, so the annotation is skipped with no error.

open as a page

What does @Transactional(propagation = REQUIRES_NEW) do, and how does it interact with the JDBC connection of an already-running transaction?

level: juniorimportance: must knowfreq 55%
basics
~20 s

REQUIRES_NEW starts a brand-new, independent transaction. If one is already running, Spring suspends it (keeps it open) and opens a second database connection for the new one, so the thread holds two connections at once.

open as a page

Why would you delay sending an email or publishing a message until after the database transaction commits, instead of doing it inline in your service method?

level: juniorimportance: must knowfreq 70%
basics
~20 s

Because the transaction might still roll back. If you email or publish before commit and the transaction then fails, you have acted on data that was never saved. Waiting until after commit ensures the side effect only happens for data that actually persisted.

open as a page

What is @TransactionalEventListener and what is its default phase?

level: juniorimportance: must knowfreq 55%
basics
~10 s

It's a Spring event listener that only fires relative to a transaction. By default it runs in the AFTER_COMMIT phase, so it executes only after the surrounding transaction successfully commits.

open as a page

Explain how @TransactionalEventListener with TransactionPhase.AFTER_COMMIT works, and the gotchas around it (default phase, no active transaction, doing DB writes in the listener).

level: middleimportance: must knowfreq 65%
basics
~20 s

You publish an event inside the transaction; a method annotated @TransactionalEventListener runs it after the transaction commits (AFTER_COMMIT is the default phase). Gotchas: if there is no active transaction the event is dropped unless fallbackExecution=true, and DB writes in the listener need a new transaction.

open as a page

Explain the four TransactionPhase values (BEFORE_COMMIT, AFTER_COMMIT, AFTER_ROLLBACK, AFTER_COMPLETION) and when each fires.

level: middleimportance: must knowfreq 50%
basics
~10 s

BEFORE_COMMIT fires just before commit (still in the tx). AFTER_COMMIT (default) fires after a successful commit. AFTER_ROLLBACK fires after a rollback. AFTER_COMPLETION fires after the tx ends either way.

open as a page

How do you run code reliably after a transaction commits, using TransactionSynchronizationManager?

level: middleimportance: must knowfreq 55%
basics
~10 s

Register a TransactionSynchronization callback via TransactionSynchronizationManager.registerSynchronization(...) and override afterCommit(). Spring invokes it only if the current transaction commits successfully.

open as a page