@Transactional, propagation, rollback rules, isolation — the most heavily-tested topic in this section.
REQUIRES_NEW does; which exceptions roll back by default
(and how to change it); the isolation levels and what each allows; and — reusing Lesson 6 — that
@Transactional is proxy-based, so self-invocation bypasses it.
@Transactional. Spring wraps the bean in an AOP proxy that begins/commits/rolls back around the method.TransactionTemplate or a PlatformTransactionManager directly in code.Both sit on top of PlatformTransactionManager, the central strategy interface.
Enable declarative transactions with @EnableTransactionManagement (Spring Boot switches it on automatically).
this.otherTxMethod() — bypasses the proxy, so that method's
transaction settings are ignored. This is the classic transaction bug.
| Implementation | Use with |
|---|---|
DataSourceTransactionManager | Plain JDBC / JdbcTemplate / MyBatis |
JpaTransactionManager | JPA (Hibernate, EclipseLink…) |
HibernateTransactionManager | Native Hibernate |
JtaTransactionManager | Global / distributed (multiple resources — XA) |
| Propagation | Behaviour |
|---|---|
REQUIRED default | Join the current transaction, or create one if none exists |
REQUIRES_NEW | Always start a new transaction, suspending any existing one |
NESTED | Run in a nested transaction (savepoint) if one exists; else like REQUIRED |
SUPPORTS | Join if one exists; else run non-transactionally |
NOT_SUPPORTED | Run non-transactionally, suspending any existing transaction |
MANDATORY | Must run in an existing transaction, else throw |
NEVER | Must not run in a transaction, else throw |
Use the current transaction if there is one: REQUIRED, SUPPORTS, MANDATORY.
Always get a fresh transaction: REQUIRES_NEW.
RuntimeException) and
Error — but not on checked exceptions (a checked exception commits by default!).
@Transactional(rollbackFor = IOException.class).@Transactional(noRollbackFor = SomeRuntimeException.class).| Level | Dirty read | Non-repeatable read | Phantom read |
|---|---|---|---|
READ_UNCOMMITTED | ❌ possible | ❌ possible | ❌ possible |
READ_COMMITTED | ✅ prevented | ❌ possible | ❌ possible |
REPEATABLE_READ | ✅ | ✅ | ❌ possible |
SERIALIZABLE | ✅ | ✅ | ✅ |
SERIALIZABLE is the most restrictive (safest, slowest); DEFAULT uses the
database's own default. Non-repeatable reads can still happen at READ_UNCOMMITTED and
READ_COMMITTED.
@Transactional runs each test method in a transaction that is rolled back
at the end — so your tests don't pollute the database. Override with @Commit (or @Rollback(false)).
ACID, quickly: Atomicity (all-or-nothing), Consistency, Isolation, Durability (committed changes survive a crash). A local transaction spans one resource; a global/distributed (JTA/XA) transaction spans several (multiple databases, message queues).
Read "Understanding the Spring Framework Transaction Abstraction", "Using @Transactional", and "Rolling Back a Declarative Transaction".
The default-rollback rule, isolation levels, and the self-invocation trap are the highest-value questions. Covers your book's whole Transaction section. Options shuffle on every load.
REQUIRES_NEW actually start (defeating self-invocation), or a
walk-through of when to use NESTED? Ask. Say "continue" for Lesson 10 — Spring Data JPA.