Spring 的事务管理通过 声明式事务(基于注解或 XML 配置)和 编程式事务(手动编码)两种方式实现,其核心机制基于 AOP(面向切面编程) 和 事务管理器(TransactionManager)。以下是详细的实现原理及流程:
一、事务管理的核心组件
1. 事务管理器(PlatformTransactionManager)
作用:统一事务操作的接口,负责事务的开启、提交、回滚和状态管理。
常见实现类:
DataSourceTransactionManager:基于 JDBC 的事务管理(单数据源)。
JpaTransactionManager:支持 JPA 的事务管理。
JtaTransactionManager:分布式事务管理(如多数据源或跨服务)。
示例配置:
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
2. 事务定义(TransactionDefinition)
作用:定义事务的传播行为、隔离级别、超时时间、是否只读等属性。
关键属性:
传播行为(Propagation):
(如 PROPAGATION_REQUIRED:如果当前没有事务,则新建事务;存在则加入)。
隔离级别(Isolation):
(如 ISOLATION_READ_COMMITTED:避免脏读)。
超时时间(Timeout):事务的最长执行时间(秒)。
只读(Read-Only):优化数据库访问(如只读查询)。
3. 事务状态(TransactionStatus)
作用:记录事务的运行时状态(如是否为新事务、是否已回滚)。
二、声明式事务的实现(基于 @Transactional 注解)
1. @Transactional 注解
作用:标记方法或类需要事务管理。
常用属性:
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.DEFAULT,
timeout = 30,
readOnly = false,
rollbackFor = Exception.class
)
public void transferMoney() { ... }
2. AOP 代理机制
实现原理:
代理对象生成:
Spring 通过 AOP 为 @Transactional 标记的类生成代理对象(JDK 动态代理或 CGLIB 代理)。
拦截方法调用:
代理对象拦截目标方法,在方法执行前后管理事务。
源码入口:
TransactionInterceptor(实现 MethodInterceptor,负责事务逻辑)。
3. 事务执行流程
1. 开启事务(begin)
-> 调用目标方法(invoke)
-> 方法执行成功:提交事务(commit)
-> 方法抛出异常:回滚事务(rollback)
4. 事务同步与资源绑定
资源绑定:事务管理器将数据库连接(Connection)绑定到当前线程的 ThreadLocal。
关键类:
TransactionSynchronizationManager 管理线程相关的事务资源。
三、编程式事务的实现
1. 使用 TransactionTemplate
@Autowired
private TransactionTemplate transactionTemplate;
public void transferMoney() {
transactionTemplate.execute(status -> {
try {
// 业务逻辑
accountDao.deductMoney(fromAccount, amount);
accountDao.addMoney(toAccount, amount);
return true;
} catch (Exception e) {
status.setRollbackOnly(); // 标记回滚
return false;
}
});
}
2. 直接使用 PlatformTransactionManager
@Autowired
private PlatformTransactionManager transactionManager;
public void transferMoney() {
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
// 业务逻辑
accountDao.deductMoney(fromAccount, amount);
accountDao.addMoney(toAccount, amount);
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
}
}
四、事务传播行为详解
传播行为(Propagation) 说明
REQUIRED(默认) 如果当前存在事务,则加入;否则新建事务。
REQUIRES_NEW 无论当前是否存在事务,都新建事务。
SUPPORTS 如果当前存在事务,则加入;否则以非事务方式执行。
NOT_SUPPORTED 以非事务方式执行,若当前存在事务,则将其挂起。
MANDATORY 必须在事务中执行,否则抛出异常。
NEVER 必须在非事务中执行,否则抛出异常。
NESTED 如果当前存在事务,则在嵌套事务中执行(支持部分回滚)。
五、事务回滚规则
1. 默认回滚策略
回滚:运行时异常(RuntimeException)和错误(Error)。
不回滚:检查型异常(Exception 的子类,如 IOException)。
2. 自定义回滚
@Transactional(rollbackFor = IOException.class) // 指定异常回滚
public void saveData() throws IOException { ... }
六、常见问题与解决方案
1. 事务不生效
原因:
方法非 public,代理无法生效。
自调用(类内部方法调用绕过代理)。
异常被捕获未抛出。
解决:
使用 public 方法。
通过 AOP 上下文获取代理对象调用。
抛出异常或手动回滚。
2. 多数据源事务管理
解决:
使用 JtaTransactionManager 或 ChainedTransactionManager(已废弃),或结合 @Transactional 指定事务管理器:
@Transactional(transactionManager = "db1TransactionManager")
public void operationOnDB1() { ... }
七、总结
Spring 事务管理通过 声明式事务(@Transactional + AOP)和 编程式事务(TransactionTemplate)实现,核心依赖:
事务管理器(PlatformTransactionManager):统一事务操作。
AOP 代理:拦截方法,管理事务生命周期。
传播行为与隔离级别:控制事务边界和数据一致性。