skip to content

PlatformTransactionManager SPI

PlatformTransactionManager reduces every backend to getTransaction, commit and rollback against a TransactionDefinition. Understanding that SPI is what lets you explain why one annotation works over JDBC, JPA and JTA alike.

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

questions

5

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

level: juniorimportance: must knowfreq 60%

answer

  1. Central SPI in spring-tx
  2. getTransaction / commit / rollback
  3. TransactionDefinition in, TransactionStatus out
  4. @Transactional and TransactionTemplate drive it
  5. Swap impl for JDBC / JPA / JTA

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).

solid answer

~30 s

PlatformTransactionManager is the central strategy interface (SPI) of Spring's transaction infrastructure, living in the spring-tx module. It has three methods: TransactionStatus getTransaction(TransactionDefinition) starts a new transaction or joins the current one based on the requested propagation; void commit(TransactionStatus) commits it; void rollback(TransactionStatus) undoes it. Everything else in Spring transactions — @Transactional, TransactionTemplate — ultimately drives this interface. Because it is an abstraction, the same code works whether the backend is plain JDBC (DataSourceTransactionManager), JPA (JpaTransactionManager), or JTA (JtaTransactionManager); you just swap the implementation bean.

code

java · 16 lines
java
public interface PlatformTransactionManager extends TransactionManager {
    TransactionStatus getTransaction(TransactionDefinition definition)
            throws TransactionException;
    void commit(TransactionStatus status) throws TransactionException;
    void rollback(TransactionStatus status) throws TransactionException;
}

// Programmatic use (what @Transactional does under the hood):
TransactionStatus status = txManager.getTransaction(new DefaultTransactionDefinition());
try {
    // ... business work ...
    txManager.commit(status);
} catch (RuntimeException ex) {
    txManager.rollback(status);
    throw ex;
}

go deeper

for a junior

Know the interface name, the three methods, and that it is Spring's core transaction abstraction.

for a middle

Connect it to @Transactional and TransactionTemplate, and know the argument/return types.

for a senior

Explain the commit-becomes-rollback-only edge case and how propagation is decided inside getTransaction.

for a principal

Discuss it as a stable SPI boundary enabling backend swap and reactive counterpart (ReactiveTransactionManager).

## What it is `PlatformTransactionManager` is the **central interface** (a Service Provider Interface, SPI) of Spring's transaction support, defined in the `org.springframework.transaction` package of the `spring-tx` module. A *transaction* is a unit of work that either fully succeeds (**commit**) or is fully undone (**rollback**) — it never leaves the system half-changed. Spring does not implement transactions itself; it defines this interface as a **strategy** and delegates the real work to a backend (a database driver, an ORM, or an application-server transaction coordinator). Your business code stays identical regardless of backend. ## The three methods ```java public interface PlatformTransactionManager extends TransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; } ``` - **`getTransaction(TransactionDefinition)`** — asks for a transaction. The `TransactionDefinition` argument describes *how* it should behave: **propagation** (start a new one vs. join an existing one), **isolation** level, **timeout**, and **read-only** hint. The method returns a `TransactionStatus` handle representing the (possibly newly created, possibly already-active) transaction. If you pass `null`, defaults are used. - **`commit(TransactionStatus)`** — attempts to commit the transaction represented by that status. If the status was marked rollback-only, commit will instead roll back and throw `UnexpectedRollbackException`. - **`rollback(TransactionStatus)`** — rolls back, undoing all changes. ## How it fits together You rarely call these methods yourself. In practice: - **Declarative** transactions: the `@Transactional` annotation is handled by an AOP proxy whose `TransactionInterceptor` calls `getTransaction` before your method, then `commit` or `rollback` after. - **Programmatic** transactions: `TransactionTemplate` wraps the same three calls around a callback. ## Key terms - **SPI** — a contract Spring defines and different providers implement. You (or Spring Boot) pick the implementation. - **`TransactionStatus`** — a runtime handle: tells you whether the transaction is new, lets you mark it rollback-only, manages savepoints. - **`TransactionDefinition`** — the read-only *specification* of the desired transaction (propagation, isolation, timeout, read-only, name). ## Why it matters Because the abstraction is uniform, moving from a single JDBC DataSource to JPA, or to distributed JTA transactions across two resources, is mostly a matter of registering a different `PlatformTransactionManager` bean — your annotated service code does not change.

  • Do you usually call getTransaction/commit/rollback yourself?
    No. Normally @Transactional (via TransactionInterceptor) or TransactionTemplate makes those calls for you. Direct calls are rare and only for fine-grained programmatic control.
  • What does the TransactionDefinition argument carry?
    The desired propagation behavior, isolation level, timeout, read-only flag, and an optional transaction name — the specification of how the transaction should behave.

saying these in an interview costs you the question

  • Claiming PlatformTransactionManager itself talks SQL or manages a connection pool (it delegates to a backend).
  • Thinking commit always commits — it rolls back and throws UnexpectedRollbackException if the transaction was marked rollback-only.
  • Saying it has methods like begin() — the method is getTransaction().

context

open as a page

Which PlatformTransactionManager implementation would you choose for plain JDBC, for JPA, and for JTA — and what goes wrong if you use the JDBC one with JPA?

level: middleimportance: must knowfreq 55%

basics

~10 s

Plain JDBC: DataSourceTransactionManager. JPA: JpaTransactionManager. JTA/distributed: JtaTransactionManager. Using the JDBC one with JPA fails to manage the EntityManager, so the persistence context isn't flushed/synchronized correctly.

open as a page

When you put @Transactional on a method, how does Spring get from that annotation to PlatformTransactionManager.getTransaction/commit/rollback? And how do you handle multiple transaction managers?

level: seniorimportance: should knowfreq 45%

basics

~10 s

An AOP proxy wraps the bean. Its TransactionInterceptor reads the @Transactional attributes, calls getTransaction before your method, then commit on success or rollback on a matching exception. With several managers, name one via @Transactional("managerBeanName").

open as a page

Explain the roles of TransactionDefinition and TransactionStatus in the PlatformTransactionManager contract. How do they differ?

level: seniorimportance: should knowfreq 40%

basics

~10 s

TransactionDefinition is the input describing how the transaction should behave (propagation, isolation, timeout, read-only). TransactionStatus is the output handle representing the running transaction, letting you check if it's new and mark it rollback-only.

open as a page

Why did Spring introduce the PlatformTransactionManager abstraction instead of exposing JTA/UserTransaction directly, and what are the design and reactive implications of this SPI boundary?

level: principalimportance: nice to knowfreq 22%

basics

~10 s

It decouples business code from the transaction backend. One uniform strategy lets you switch between local JDBC/JPA and global JTA without changing application code, and it enabled a parallel reactive contract (ReactiveTransactionManager).

open as a page