8 Hidden Spring Transaction Pitfalls That Can Break Your Java Apps
This article reveals ten common Spring transaction pitfalls—including private methods, final modifiers, self‑invocation, missing @Service, wrong propagation, non‑transactional databases, swallowed or wrong exceptions, multi‑threaded calls, and nested transaction rollbacks—that can silently disable transaction management in Java backend projects.
For Java developers, Spring's transaction management is familiar, but it contains many hidden pitfalls that can cause transactions to silently fail.
1. Incorrect access modifier
If a @Transactional method is declared private, Spring's proxy cannot intercept it, so the transaction is ignored.
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional
private void add(UserModel userModel) {
userMapper.insertUser(userModel);
}
}2. Method declared final
Final methods cannot be overridden by the proxy, preventing transaction activation.
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional
public final void add(UserModel userModel) {
userMapper.insertUser(userModel);
}
}3. Self‑invocation
Calling another @Transactional method from within the same class uses the raw this reference, bypassing the proxy, so the inner method runs without a transaction.
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional
public void add(UserModel userModel) {
userMapper.insertUser(userModel);
updateStatus(userModel);
}
@Transactional
public void updateStatus(UserModel userModel) {
// …
}
}4. Bean not managed by Spring
Without @Service (or another stereotype), the class is not a Spring bean and its methods are never proxied.
// @Service is missing
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional
public void add(UserModel userModel) {
userMapper.insertUser(userModel);
}
}5. Wrong propagation setting
Using Propagation.NEVER disables transaction creation; only REQUIRED, REQUIRES_NEW and NESTED start a new transaction.
@Transactional(propagation = Propagation.NEVER)
public void add(UserModel userModel) {
userMapper.insertUser(userModel);
}6. Database engine without transaction support
Tables created with MyISAM (or similar) support only table locks and cannot participate in transactions.
7. Swallowing exceptions
Catching exceptions without rethrowing prevents Spring from detecting a failure, so the transaction is not rolled back.
@Transactional
public void add(UserModel userModel) {
try {
userMapper.insertUser(userModel);
} catch (Exception e) {
log.error(e.getMessage(), e);
// no rethrow
}
}8. Throwing checked exceptions
Spring rolls back only on RuntimeException or Error by default; throwing a checked Exception will not trigger a rollback.
@Transactional
public void add(UserModel userModel) throws Exception {
try {
userMapper.insertUser(userModel);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new Exception(e);
}
}9. Multi‑threaded calls
When a @Transactional method starts a new thread, the new thread obtains a different database connection, resulting in separate transactions.
@Transactional
public void add(UserModel userModel) throws Exception {
userMapper.insertUser(userModel);
new Thread(() -> roleService.doOtherThing()).start();
}10. Nested transaction rolls back the outer work
Using Propagation.NESTED creates a savepoint, but if the outer transaction rolls back, the inner work is also undone.
@Transactional
public void add(UserModel userModel) throws Exception {
userMapper.insertUser(userModel);
roleService.doOtherThing(); // @Transactional(propagation = Propagation.NESTED)
}Understanding these pitfalls helps avoid silent transaction failures in Spring‑based backend 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.
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.
