skip to content

timeout Attribute

The timeout attribute sets a deadline that Spring applies as a statement query timeout, failing with TransactionTimedOutException when it expires. It comes up in scenarios about long transactions holding locks.

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

questions

5

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

level: juniorimportance: must knowfreq 40%

answer

  1. Unit = seconds, not ms
  2. Default TIMEOUT_DEFAULT = -1 (none)
  3. TransactionTimedOutException on expiry
  4. Caps lock + connection hold time
  5. timeout on @Transactional / TransactionTemplate

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.

solid answer

~30 s

The timeout attribute caps the maximum duration of a transaction, expressed in seconds (an int). You set it declaratively, e.g. @Transactional(timeout = 5), or via TransactionTemplate.setTimeout(5). When the transaction starts, Spring records a deadline; when the wall-clock time exceeds it, Spring refuses to let the transaction proceed and throws org.springframework.transaction.TransactionTimedOutException, marking the transaction rollback-only. The default value is TransactionDefinition.TIMEOUT_DEFAULT (-1), meaning 'no Spring-imposed timeout — use the underlying transaction system's default,' which for most JDBC/JPA setups is effectively unlimited. It is primarily used to stop runaway queries or transactions from holding database locks and connections too long.

code

java · 12 lines
java
import org.springframework.transaction.annotation.Transactional;

@Service
public class ReportService {

    // Abort and roll back if this transaction runs longer than 5 seconds.
    @Transactional(timeout = 5)
    public Report generateHeavyReport() {
        // long-running queries here are bounded by the 5s deadline
        return buildReport();
    }
}

go deeper

for a junior

Know it's seconds, it's opt-in (default -1 = none), and expiry throws TransactionTimedOutException with a rollback.

for a middle

Also know timeoutString and that the default defers to the underlying tx manager (usually unlimited).

for a senior

Add that it's stored in TransactionDefinition and only applies to the transaction Spring actually starts.

for a principal

Frame it as a resource-protection lever (lock/connection hold time) that must be coordinated with pool and DB-level timeouts.

## What it is Every Spring transaction is described by a `org.springframework.transaction.TransactionDefinition`. One of its properties is the **timeout**, an `int` measured in **seconds**, exposed through `getTimeout()`. You normally set it declaratively: ```java @Transactional(timeout = 5) public void doWork() { ... } ``` or programmatically via `TransactionTemplate.setTimeout(5)` / `DefaultTransactionDefinition.setTimeout(5)`. ## The unit is seconds This trips people up: the attribute is **seconds**, not milliseconds. `timeout = 5` means five seconds. There is also `timeoutString` (Spring 5.3+) for placeholder-resolved values like `@Transactional(timeoutString = "${tx.timeout}")`. ## The default If you don't set it, the value is `TransactionDefinition.TIMEOUT_DEFAULT`, which is the constant `-1`. This means **Spring imposes no timeout of its own** and defers to the underlying transaction infrastructure's default. For a plain JDBC `DataSourceTransactionManager` or `JpaTransactionManager`, that usually means **no timeout at all** — a query can run indefinitely until the driver, database, or connection pool kills it. So `timeout` is opt-in. ## What happens on expiry When the deadline passes, Spring throws `org.springframework.transaction.TransactionTimedOutException` (an unchecked `TransactionException` subclass). The transaction is marked rollback-only and rolled back. ## When to use it - To bound how long a transaction can hold database **locks** and a pooled **connection**. - As a safety net against runaway queries or slow external-driven work inside a transaction. - Set it tighter for interactive/user-facing paths, looser (or omit) for batch jobs. ## Gotcha to remember The timeout only bounds the transaction that Spring actually **starts**. If your method joins an already-running transaction (the common `PROPAGATION_REQUIRED` case), your `timeout` value is, by default, silently ignored — the outer transaction's timeout wins.

  • What is the default timeout and what does it mean?
    TransactionDefinition.TIMEOUT_DEFAULT, which is -1. It means Spring imposes no timeout and uses the underlying transaction system's default, which for typical JDBC/JPA is effectively unlimited.
  • Which exception is thrown when the timeout is exceeded?
    org.springframework.transaction.TransactionTimedOutException, an unchecked subclass of TransactionException; the transaction is rolled back.

saying these in an interview costs you the question

  • Thinking the value is in milliseconds
  • Believing there is a default timeout like 30s when you omit it
  • Thinking timeout throws a checked exception you must declare

context

open as a page

Under the hood, how does Spring actually enforce the transaction timeout? Trace it from TransactionDefinition to the JDBC layer.

level: middleimportance: should knowfreq 32%

basics

~20 s

When the transaction starts, Spring turns the N-second timeout into a deadline stored on the resource holder (e.g. ConnectionHolder). Before each JDBC statement runs, Spring applies the remaining time via Statement.setQueryTimeout(), and if the deadline has already passed it throws TransactionTimedOutException.

open as a page

Why might a @Transactional(timeout = ...) value appear to be ignored at runtime? Cover propagation and what the timeout does and doesn't bound.

level: seniorimportance: should knowfreq 28%

basics

~20 s

The timeout only applies to the transaction Spring actually starts. If your method joins an existing (PROPAGATION_REQUIRED) transaction, your timeout is silently ignored by default. Also, timeout is enforced only at database-statement boundaries, so pure CPU/sleep work between queries isn't interrupted mid-flight.

open as a page

Tell me about TransactionTimedOutException: what type is it, when is it thrown, and how does it differ from a database lock timeout or a JDBC query timeout?

level: seniorimportance: should knowfreq 22%

basics

~20 s

TransactionTimedOutException is Spring's unchecked exception (a TransactionException) thrown when a transaction's timeout deadline has passed and Spring tries to use the resource again. It forces a rollback. It's distinct from a DB lock timeout or a JDBC query timeout, which are database-level errors surfaced as SQLExceptions.

open as a page

You want reliable time bounds on database work in a high-throughput service. Where does Spring's @Transactional timeout fall short, and how would you design defense-in-depth around it?

level: principalimportance: nice to knowfreq 12%

basics

~20 s

Spring's timeout depends on the JDBC driver honoring setQueryTimeout and is only checked at statement boundaries, so it won't catch driver no-ops or long non-DB work. Layer it with DB-side statement_timeout and lock_timeout, keep external calls out of transactions, and set connection-pool timeouts.

open as a page