Mastering Java Exceptions and @Transactional: When Do Transactions Roll Back?
This article explains Java exception categories, distinguishing checked from unchecked exceptions, and shows how Spring's @Transactional annotation controls transaction rollbacks, including configurations for rolling back on checked exceptions, preventing rollback on unchecked ones, and best practices for applying @Transactional in backend services.
1. Exception Classification
First, let’s look at exception classification.
Errors will always cause a transaction rollback.
Exception is the base class for all exceptions; it is divided into runtime exceptions (RuntimeException) and non‑runtime (checked) exceptions.
Checked exceptions (also called “checked”): all subclasses of Exception except RuntimeException.
Unchecked exceptions (often called “unchecked”): RuntimeException and its subclasses, as well as Errors.
If a runtime exception is not handled, the thread may terminate and the main program ends. To avoid termination, all runtime exceptions must be caught, logged, and discarded without affecting the processing of normal data.
The Java compiler forces us to handle checked exceptions, so we often need many catch blocks to deal with possible exceptions.
2. @Transactional Usage
When @Transactional is used with its default settings, the transaction will roll back for RuntimeException subclasses and Errors, but not for checked exceptions thrown from the method.
Make checked exceptions trigger rollback: add @Transactional(rollbackFor = Exception.class) to the method.
Prevent unchecked exceptions from rolling back: use @Transactional(notRollbackFor = RuntimeException.class).
Methods that do not need transaction management (read‑only): @Transactional(propagation = Propagation.NOT_SUPPORTED).
Note: If an exception is caught and swallowed inside a try‑catch block, the transaction will not roll back. To force a rollback, re‑throw the exception after handling.
Spring’s recommendation is to place @Transactional on concrete classes or methods, not on interfaces, because the annotation is not inherited and class‑based proxies may ignore it.
Avoid putting locked operations inside a transaction unless necessary; perform simple read queries before the transaction and reserve the transaction for insert, update, delete, 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.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
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.
