Transaction Pitfalls (Part 4)
Multi-threaded Calls and Spring Transaction Mechanism
Problem Causes:
- Spring stores transaction state in ThreadLocal variables
- Newly created threads cannot access parent thread’s ThreadLocal variables
- Causing child threads to fail to inherit parent thread’s transaction context
Solutions:
- Avoid creating new threads in transaction methods
- Use programmatic transaction management
- Use distributed transaction framework (such as Seata)
Exception Catching and Spring Transaction Rollback Mechanism
Problem Cause:
- When an exception is caught and handled within a method’s try-catch block, Spring’s transaction interceptor cannot perceive this exception
Solutions:
- Manually roll back transaction in catch block
- Re-throw the exception
- Configure rollbackFor attribute of @Transactional annotation
@Transactional
public void someMethod() {
try {
// Business code
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
Manual Exception Throwing
Problem Cause:
- Spring only rolls back transactions for RuntimeException and Error by default
Solutions:
- Configure rollbackFor rules
- Wrap checked exceptions and throw as runtime exceptions
@Transactional(rollbackFor = {IOException.class, SQLException.class})
public void businessMethod() throws IOException {
// Business logic
}