When Should @Transactional Roll Back? Mastering Exception Handling in Spring
This article explains Java exception categories, how Spring's @Transactional decides which exceptions trigger a rollback, and provides practical annotation configurations to control rollback behavior for both checked and unchecked exceptions.
The author, a self‑described architect, starts by citing an Alibaba Java coding rule that warns the edit method must specify rollbackFor in @Transactional or handle rollback manually.
Exception Classification
In Spring, error types always cause a transaction rollback. Exception is the base class for all exceptions and splits into two groups:
Checked exceptions (non‑runtime): all subclasses of Exception except RuntimeException.
Unchecked exceptions: RuntimeException and its subclasses, plus Error.
If a runtime exception is not caught, the thread terminates; therefore, to keep the application alive you must catch all runtime exceptions, discard the faulty data, and log the incident.
Checked exceptions must be declared or caught because the Java compiler enforces it. Typical examples are IOException, SQLException, or custom exceptions extending Exception. Developers often end up writing many try‑catch blocks to satisfy the compiler.
How @Transactional Handles Rollback
Spring’s transaction infrastructure rolls back automatically only for runtime and unchecked exceptions (including Error). Checked exceptions do not trigger a rollback by default.
Customizing Rollback Behavior
Make checked exceptions roll back: @Transactional(rollbackFor = Exception.class) Prevent unchecked exceptions from rolling back: @Transactional(notRollbackFor = RuntimeException.class) Exclude transaction management for read‑only methods: @Transactional(propagation = Propagation.NOT_SUPPORTED) If an exception is caught inside the method (e.g., try { … } catch (Exception e) { … }) the transaction will not roll back unless the exception is re‑thrown.
Best Practices
Apply @Transactional on concrete classes rather than interfaces, because Spring’s proxy mechanism may ignore annotations on interfaces when using class‑based proxies.
Keep transactional methods simple; avoid placing heavy logic or long‑running locks inside a transaction. Perform plain queries before the transaction and reserve the transaction for write, delete, update, or locked‑read operations.
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 Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
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.
