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?
answer
- Extends TransactionException -> RuntimeException (unchecked)
- Thrown by ResourceHolderSupport.checkTransactionTimeout
- Sets rollbackOnly then throws at a boundary
- Query timeout -> QueryTimeoutException (different)
- Lock wait -> PessimisticLockingFailureException (different)
basics
~20 sTransactionTimedOutException 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.
solid answer
~40 sorg.springframework.transaction.TransactionTimedOutException extends TransactionException, which is a RuntimeException — so it's unchecked and, being a Spring exception, triggers rollback under the default rules. It's thrown by Spring's own code: ResourceHolderSupport.checkTransactionTimeout, invoked from getTimeToLiveInMillis/Seconds, throws it when the recorded deadline is in the past, marking the holder rollback-only. Contrast with two lower-level things Spring may leverage but which are different exceptions: a JDBC query timeout (from Statement.setQueryTimeout being exceeded) surfaces as a SQLException, typically translated by Spring to QueryTimeoutException; and a database lock/statement timeout (e.g., Postgres lock_timeout, MySQL innodb_lock_wait_timeout) also comes back as a driver SQLException, translated to a PessimisticLockingFailureException or similar. So TransactionTimedOutException specifically means 'Spring's transaction deadline elapsed and was detected at a boundary,' not 'the database killed my query.'
code
java · 9 lines// TransactionTimedOutException is unchecked and forces rollback.
try {
reportService.generateHeavyReport(); // @Transactional(timeout = 5)
} catch (org.springframework.transaction.TransactionTimedOutException ex) {
// The tx is already rollback-only. Don't 'recover' and continue the same tx.
log.warn("Report tx exceeded its 5s budget: {}", ex.getMessage());
// Distinct from QueryTimeoutException (DB cancelled one query) and
// PessimisticLockingFailureException (DB lock wait timed out).
}go deeper
Know it's unchecked and means the transaction ran past its timeout and rolled back.
Place it in the TransactionException hierarchy and know it's thrown by Spring, not the driver.
Distinguish it from QueryTimeoutException and PessimisticLockingFailureException and explain rollback-only marking.
Use the distinction to design layered timeouts (Spring tx timeout + DB statement/lock timeouts) and correct error handling that doesn't try to continue a rollback-only tx.
## Type and hierarchy `org.springframework.transaction.TransactionTimedOutException` extends `TransactionException`, which extends `NestedRuntimeException` -> `RuntimeException`. Therefore it is **unchecked** (you don't declare it) and, under Spring's default rollback rules (`RuntimeException`/`Error` -> rollback), it causes the transaction to roll back. ## Where and when it's thrown It's thrown by **Spring itself**, not the driver. `ResourceHolderSupport` records an absolute `deadline` when the timeout is set. Its `checkTransactionTimeout(boolean deadlineReached)` method does: ```java if (deadlineReached) { setRollbackOnly(); throw new TransactionTimedOutException("Transaction timed out: deadline was " + this.deadline); } ``` This fires from `getTimeToLiveInMillis()/getTimeToLiveInSeconds()` — i.e., whenever Spring computes the remaining budget (to apply a query timeout or otherwise use the resource) and finds the deadline already passed. So it's detected at a **statement/resource boundary**, and it sets `rollbackOnly` before throwing. ## How it differs from neighbours 1. **JDBC query timeout exceeded** — `Statement.setQueryTimeout(n)` was set (possibly by Spring's own timeout machinery) and the DB cancelled the running query. The driver throws a `SQLException` (often with a timeout SQL state). Spring's `SQLExceptionTranslator` typically maps it to `org.springframework.dao.QueryTimeoutException` (a `TransientDataAccessException`). This is 'the DB stopped one query,' whereas `TransactionTimedOutException` is 'Spring's overall transaction budget elapsed.' 2. **Database lock wait timeout** — e.g., Postgres `lock_timeout`, MySQL `innodb_lock_wait_timeout`. The row you want is locked by another transaction; after the DB's own wait limit, the driver throws a `SQLException`, which Spring translates to `PessimisticLockingFailureException` / `CannotAcquireLockException`. Again, driver-originated, not Spring's transaction timeout. 3. **`javax.persistence.QueryTimeoutException` / `LockTimeoutException`** — JPA-level equivalents when using an `EntityManager`; Spring's JPA exception translation maps these into the `org.springframework.dao` hierarchy. ## Practical consequences - Because it's a Spring `RuntimeException`, catching it and swallowing it does **not** un-mark the transaction — the transaction is already rollback-only; the commit will fail with `UnexpectedRollbackException` if you try to proceed. - When you see `TransactionTimedOutException` in logs, the fix is usually to widen the `timeout`, speed up the work, move slow non-DB work out of the transaction, or split into `REQUIRES_NEW` units — not to add try/catch. - For robust systems, layer the Spring timeout with DB-side `statement_timeout`/`lock_timeout` so a hung query is killed even if `setQueryTimeout` isn't honored by the driver. ## Message you'll see Typical log: `org.springframework.transaction.TransactionTimedOutException: Transaction timed out: deadline was <timestamp>`.
- Is TransactionTimedOutException checked or unchecked, and does it roll back?Unchecked — it extends TransactionException / RuntimeException. Under Spring's default rules a RuntimeException rolls the transaction back, and the exception itself marks the holder rollback-only before being thrown.
- If the database cancels a single query that exceeded setQueryTimeout, do you get a TransactionTimedOutException?Not directly — that's a driver SQLException, which Spring translates to QueryTimeoutException. TransactionTimedOutException comes from Spring's own deadline check at a resource boundary.
saying these in an interview costs you the question
- Saying it's a checked exception you must declare
- Confusing it with SQL/JDBC query-timeout SQLExceptions or lock-timeout exceptions
- Believing catching it lets you keep using the same transaction