Spring事务管理深度解析:原理、实践与陷阱
一、事务基础概念
ACID原则
- 原子性(Atomicity):事务内的操作要么全部成功,要么全部回滚
- 一致性(Consistency):事务前后数据库状态保持一致
- 隔离性(Isolation):并发事务间相互隔离
- 持久性(Durability):事务提交后数据永久存储
二、Spring事务核心接口
java
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition);
void commit(TransactionStatus status);
void rollback(TransactionStatus status);
}
public interface TransactionDefinition {
int getIsolationLevel();
int getPropagationBehavior();
int getTimeout();
boolean isReadOnly();
}
三、事务配置方式
1. 声明式事务(推荐)
xml
<!-- XML配置 -->
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
java
// 注解驱动
@Configuration
@EnableTransactionManagement
public class AppConfig {
@Bean
public PlatformTransactionManager transactionManager(DataSource ds) {
return new DataSourceTransactionManager(ds);
}
}
2. 编程式事务
java
transactionTemplate.execute(status -> {
try {
userDao.update(user1);
logDao.insert(log);
return true;
} catch (Exception e) {
status.setRollbackOnly();
return false;
}
});
四、@Transactional详解
属性配置
java
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
timeout = 30,
readOnly = false,
rollbackFor = {BusinessException.class},
noRollbackFor = {SystemException.class}
)
public void businessMethod() { ... }
传播行为(Propagation)
行为类型 | 说明 |
---|---|
REQUIRED(默认) | 存在事务则加入,没有则新建 |
REQUIRES_NEW | 总是新建事务,挂起当前事务 |
NESTED | 嵌套事务,使用保存点实现部分回滚 |
SUPPORTS | 存在事务则加入,没有则以非事务运行 |
NOT_SUPPORTED | 非事务执行,挂起当前事务 |
MANDATORY | 必须存在事务,否则抛异常 |
NEVER | 必须非事务执行,否则抛异常 |
隔离级别(Isolation)
级别 | 脏读 | 不可重复读 | 幻读 | 说明 |
---|---|---|---|---|
READ_UNCOMMITTED | ✓ | ✓ | ✓ | 最低隔离级别 |
READ_COMMITTED(默认) | × | ✓ | ✓ | 避免脏读 |
REPEATABLE_READ | × | × | ✓ | MySQL默认级别 |
SERIALIZABLE | × | × | × | 最高隔离级别 |
五、事务失效场景
-
非public方法:基于代理的AOP无法拦截private方法
-
自调用问题 :类内部方法调用不会经过代理对象
解决方案 :java@Autowired private ApplicationContext context; public void methodA() { context.getBean(ThisClass.class).methodB(); }
-
异常类型不匹配:默认只回滚RuntimeException和Error
-
多线程调用:不同线程属于不同事务上下文
-
错误捕获异常 :catch后未重新抛出
javatry { ... } catch (Exception e) { // 需添加:throw new RuntimeException(e); }
六、高级特性
1. 事务同步
java
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronization() {
@Override
public void afterCommit() {
// 事务提交后操作
}
});
2. 多数据源事务
java
@Bean
@Primary
public PlatformTransactionManager primaryTM(DataSource ds1) {
return new DataSourceTransactionManager(ds1);
}
@Bean
public PlatformTransactionManager secondaryTM(DataSource ds2) {
return new DataSourceTransactionManager(ds2);
}
// 使用指定事务管理器
@Transactional(transactionManager = "secondaryTM")
public void crossDatabaseOp() {...}
七、最佳实践
- 事务方法保持简短,避免远程调用
- 明确指定rollbackFor属性
- 只读查询添加@Transactional(readOnly=true)
- 嵌套事务使用PROPAGATION_NESTED
- 监控事务执行时间(超过3秒需优化)