Why Did My Spring @Transactional Rollback Fail? Uncovering a MySQL Connector Bug
An in‑depth investigation reveals that Spring’s @Transactional rollback can silently fail due to a bug in mysql‑connector‑java 8.0.28 when useLocalSessionState=true, causing auto‑commit to stay enabled; the article explains the root cause, debugging steps, and how upgrading to 8.0.29 resolves the issue.
Background
The article begins by introducing the components involved: commons-db , an internal Spring‑based multi‑datasource management library; a java‑project used for functional testing (Spring Boot 2.5.4, mysql‑connector‑java 8.0.26); a store project (Spring Boot 2.6.6, mysql‑connector‑java 8.0.28); and an Alibaba Cloud RDS instance (default isolation READ_COMMITTED, MySQL default REPEATABLE_READ).
Problem
In the store project, a method annotated with @Transactional and @DataSource throws a runtime exception (division by zero), but the inserted user record is still persisted, indicating that the transaction rollback does not take effect.
@Transactional
@DataSource(type = Type.MASTER, value = "developer")
public void addUser(ApolloUser user) {
userRepository.save(user);
int i = 1/0; // throws exception
}Assumptions
Assumption 1: The AOP proxy for @Transactional might not be active. Debug logs show the transaction lifecycle, so this is false.
Assumption 2: The commons-db component could be using different connections for commit and rollback. Logs show the same connection is used, so this is also false.
Turning Points
Turning Point 1
Running the same code in java‑project (same MySQL version) rolls back successfully, suggesting the issue is environment‑specific.
Turning Point 2
Setting the transaction isolation level to Isolation.REPEATABLE_READ in store makes rollback work, but the same isolation level in java‑project already works, so isolation alone is not the root cause.
@Transactional(isolation = Isolation.REPEATABLE_READ)
@DataSource(type = Type.MASTER, value = "developer")
public void addUser(ApolloUser user) {
userRepository.save(user);
int i = 1/0;
}Turning Point 3
Changing isolation to READ_UNCOMMITTED also makes rollback succeed, confirming that isolation is not the decisive factor. The investigation then focuses on the JDBC driver behavior.
Analysis
A typical Spring transaction creates a connection with autoCommit = false, executes the method, and on failure calls doRollback. The logs show these steps, so the problem must lie deeper, possibly in the driver.
Locating the Problem
Debugging the MySQL driver’s NativeSession.execSQL() reveals that when rollback fails, the driver never sends SET autocommit=0, leaving the connection in auto‑commit mode. Consequently, the insert is committed before the rollback can occur.
Decryption
The driver version 8.0.28 introduced a change where isAutocommit() checks a statusFlags field instead of the autoCommit flag. With useLocalSessionState=true, the driver incorrectly reports isAutocommit() as false, causing the transaction manager to skip the SET autocommit=0 command.
Reproducing the Issue
Upgrade Spring Boot to 2.6.6 (matching store ) – the bug reproduces.
Keep Spring Boot 2.5.4 and upgrade mysql‑connector‑java to 8.0.28 – the bug also reproduces.
Thus the root cause is isolated to mysql‑connector‑java 8.0.28.
Confirming the Bug
GitHub commit history for the MySQL Connector/J project shows that version 8.0.28 unintentionally changed the auto‑commit handling, and later commits reverted it, labeling the change a bug.
Fix
Release 8.0.29 fixes the auto‑commit state issue when useLocalSessionState=true (Bug #106435, #33850099).
Upgrading the MySQL driver to 8.0.29 restores correct transaction rollback behavior.
Conclusion
The observed failure of Spring @Transactional rollback was caused by a bug in mysql‑connector‑java 8.0.28 that mishandles the auto‑commit flag when useLocalSessionState=true. Upgrading to 8.0.29 or disabling useLocalSessionState resolves the issue, preventing silent data loss in many Spring‑Boot applications.
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.
