When Does @Transactional Roll Back? Mastering Spring Transaction Exceptions
This article explains Alibaba’s Java guidelines for using @Transactional, categorizes checked and unchecked exceptions, shows how Spring’s default rollback behavior works, and provides practical examples of configuring rollback rules, avoiding common pitfalls, and best practices for applying @Transactional in backend Java applications.
Alibaba Java coding guidelines state that a method must specify rollbackFor in the @Transactional annotation or explicitly roll back inside the method.
1. Classification of Exceptions
Exceptions are divided into runtime exceptions ( RuntimeException) and non‑runtime (checked) exceptions. Errors also trigger rollback by default.
Errors always cause a transaction rollback. Exception includes both runtime and checked exceptions.
Checked exceptions: all Exception subclasses except RuntimeException.
Unchecked exceptions: RuntimeException and its subclasses, plus Error.
If a runtime exception is not caught, it will terminate the thread or the main program. To prevent termination, catch all runtime exceptions, log them, and discard the faulty data without affecting normal processing.
Checked exceptions (e.g., IOException, SQLException) must be declared or caught; otherwise the code will not compile, forcing developers to write explicit try/catch blocks.
2. Writing @Transactional
By default, Spring rolls back a transaction only when a RuntimeException or Error is thrown. Checked exceptions do not trigger a rollback.
Make checked exceptions roll back: @Transactional(rollbackFor=Exception.class) Prevent unchecked exceptions from rolling back: @Transactional(notRollbackFor=RuntimeException.class) Mark a method as non‑transactional (read‑only): @Transactional(propagation=Propagation.NOT_SUPPORTED) Note: If an exception is caught with try { } catch { }, the transaction will not roll back unless the exception is re‑thrown (e.g., catch (Exception e) { throw e; }).
3. Important Tips
1. Apply @Transactional on concrete classes or methods, not on interfaces, because the annotation is not inherited and may be ignored when using class‑based proxies.
2. Keep the logic inside a transactional method simple; avoid placing heavy processing or locking inside the transaction.
3. Perform ordinary read‑only queries before entering a transaction, and reserve the transaction for write, delete, update, or lock‑based queries.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
