skip to content

REQUIRED (default)

REQUIRED joins an existing transaction or starts one, so caller and callee share a single physical transaction — and an inner failure marks the whole thing rollback-only. That rollback-only surprise is the classic follow-up.

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

questions

5

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

level: juniorimportance: must knowfreq 80%

answer

  1. Default propagation
  2. Join if exists, else start new
  3. One physical tx, one Connection
  4. Atomic across service methods
  5. Thread-bound Connection

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.

solid answer

~40 s

Propagation.REQUIRED is the default value of @Transactional. Its rule is simple: support a current transaction if one exists, otherwise create a new one. When an outer @Transactional method calls an inner @Transactional(REQUIRED) method, the inner call joins the outer's transaction instead of opening a second one — they share a single physical transaction and the same database Connection. This means both methods commit or roll back together as a unit. Because it's the default, most Spring service methods use REQUIRED without stating it explicitly. You reach for other propagations (REQUIRES_NEW, NESTED, SUPPORTS) only when you need behavior different from 'always run in one shared transaction.'

code

java · 23 lines
java
@Service
public class OrderService {

    private final InventoryService inventory;

    OrderService(InventoryService inventory) { this.inventory = inventory; }

    // REQUIRED is the default — no transaction active yet, so a new one starts here
    @Transactional
    public void placeOrder(Order order) {
        saveOrder(order);
        inventory.reserve(order); // joins THIS transaction, no new Connection
    }
}

@Service
public class InventoryService {

    @Transactional // == @Transactional(propagation = Propagation.REQUIRED)
    public void reserve(Order order) {
        // runs on the same physical transaction/Connection as placeOrder
    }
}

go deeper

for a junior

Know it's the default and the 'join or start' rule.

for a middle

Explain the shared physical transaction and single Connection across nested calls.

for a senior

Connect REQUIRED to atomicity guarantees and contrast with REQUIRES_NEW/NESTED.

for a principal

Frame REQUIRED as the default that shapes transaction boundaries and unit-of-work design across a modular service layer.

## What propagation means `@Transactional` in Spring wraps a method in a transaction using an AOP proxy. **Propagation** answers the question: 'when this method is called, and there might *already* be a transaction running, what should happen?' The setting is `@Transactional(propagation = Propagation.REQUIRED)`, and REQUIRED is the **default** — writing `@Transactional` alone gives you REQUIRED. ## The REQUIRED rule Exactly two cases: 1. **No transaction active** → Spring's `PlatformTransactionManager` (e.g. `DataSourceTransactionManager` for JDBC/JPA) **starts a new physical transaction**: it grabs a `Connection` from the `DataSource`, sets `autoCommit=false`, and binds that Connection to the current thread (via `TransactionSynchronizationManager`). 2. **A transaction is already active** → the method **joins (participates in) the existing one**. No new Connection, no new physical transaction. Spring just notes that another layer has entered. Because the Connection is bound to the thread, any `@Repository`/`JdbcTemplate`/JPA `EntityManager` used inside will transparently use that same Connection. ## Why it matters Consider `OrderService.placeOrder()` (`@Transactional`) calling `InventoryService.reserve()` (`@Transactional`). With REQUIRED on both, there is **one** transaction, **one** Connection. If `reserve()` fails, the entire `placeOrder()` rolls back — inventory and order changes are atomic. That 'all-or-nothing across service methods' behavior is exactly why REQUIRED is the sensible default. ## Terms defined - **Physical transaction**: the actual DB transaction on one Connection. - **Logical transaction**: each `@Transactional` scope entered. Nested REQUIRED calls create nested *logical* transactions inside *one* physical transaction. - **PlatformTransactionManager**: Spring's abstraction that begins/commits/rolls back; REQUIRED is interpreted by `AbstractPlatformTransactionManager`. ## Common gotcha (preview) Because REQUIRED joins the existing transaction, a rollback triggered inside the inner method dooms the whole shared transaction — you can't 'catch it and carry on' cleanly. That is covered in follow-up questions. ## When to use Use REQUIRED (the default) whenever a method should be part of the caller's atomic unit of work. Choose something else only for a deliberate reason: REQUIRES_NEW for an independent commit (audit log, outbox), SUPPORTS for read helpers, MANDATORY to assert a caller already opened one.

  • What propagation is used if you write @Transactional with no arguments?
    Propagation.REQUIRED — it is the default. (The default isolation is also DEFAULT, meaning the database's default.)
  • If placeOrder and reserve are both REQUIRED, how many database Connections are used?
    One. The inner call joins the outer's physical transaction and reuses the same thread-bound Connection.

saying these in an interview costs you the question

  • Thinking REQUIRED always starts a brand-new transaction even when one is already active.
  • Believing each @Transactional method gets its own Connection.
  • Confusing REQUIRED with REQUIRES_NEW (which always suspends and starts a fresh transaction).

context

open as a page

Under REQUIRED, an inner method throws and rolls back but the outer catches the exception and continues. What happens at commit, and why?

level: seniorimportance: must knowfreq 70%

basics

~10 s

The inner failure marks the shared transaction rollback-only. Even though the outer swallowed the exception, when it tries to commit Spring refuses and throws UnexpectedRollbackException — the whole transaction rolls back.

open as a page

With nested REQUIRED calls, what is shared between the outer and inner methods, and what is the difference between a physical and a logical transaction?

level: middleimportance: should knowfreq 55%

basics

~20 s

They share one physical transaction and one JDBC Connection. Each @Transactional method is a separate logical scope, but nested REQUIRED scopes all map onto the single physical transaction, so they commit or roll back together.

open as a page

When would you choose REQUIRES_NEW over REQUIRED, and what does that change about connections and commit boundaries?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Use REQUIRES_NEW when a piece of work must commit or roll back independently of the caller — like an audit log that should persist even if the main transaction fails. It suspends the current transaction and runs on a second, separate Connection.

open as a page

How does defaulting to REQUIRED shape where you place transaction boundaries in a layered/modular service architecture, and what pitfalls arise from the shared-transaction model at scale?

level: principalimportance: should knowfreq 35%

basics

~20 s

Because REQUIRED joins any active transaction, the boundary is set by the outermost @Transactional call — usually the top-level service method (the unit of work). Everything it calls shares that transaction, so keep those methods focused and avoid slow I/O inside them.

open as a page