Spring 事务的实现方式与实现原理
一、Spring 事务的两种实现方式
1. 编程式事务(Programmatic Transaction)
通过代码手动控制事务的开启、提交、回滚。
示例:
TransactionTemplate template = new TransactionTemplate(transactionManager);
template.execute(status -> {
// your business logic
if (error) {
status.setRollbackOnly();
}
return null;
});
灵活但侵入性强,代码耦合度高,不推荐在常规开发中使用。
2. 声明式事务(Declarative Transaction)
通过注解或 XML 声明来管理事务,最常用的方式。
示例:
@Service
public class UserService {
@Transactional
public void createUser() {
// 执行业务逻辑
}
}
推荐方式,结合 Spring AOP 拦截事务方法,在方法调用前后自动进行事务管理。
二、Spring 事务的核心组件
组件名 | 说明 |
---|---|
@Transactional |
声明事务属性(传播行为、隔离级别、回滚规则等) |
TransactionInterceptor |
拦截方法并处理事务逻辑的核心拦截器 |
PlatformTransactionManager |
事务管理器接口,支持 JDBC、JPA、Hibernate 等 |
DataSourceTransactionManager |
JDBC 事务管理器(常用于 MyBatis/JDBC) |
TransactionAttributeSource |
读取事务注解属性的接口实现(如注解解析器) |
三、Spring 声明式事务实现原理(基于 AOP)
核心流程:
-
容器启动时,Spring 会扫描并解析
@Transactional
注解 - 通过 AOP 创建代理对象(JDK 动态代理或 CGLIB)
- 方法调用时,进入事务拦截器
TransactionInterceptor
- 拦截器内部调用
PlatformTransactionManager
:- 调用
getTransaction()
开启事务 - 执行目标方法
- 如果无异常,提交事务
- 如发生异常,回滚事务
- 调用
简化伪代码逻辑:
TransactionStatus status = txManager.getTransaction(...);
try {
method.invoke(target); // 执行目标方法
txManager.commit(status);
} catch (Throwable ex) {
txManager.rollback(status);
throw ex;
}
四、事务属性解析
@Transactional
注解支持配置多个属性,用于控制事务行为:
属性 | 含义与说明 |
---|---|
propagation | 事务传播行为(如 REQUIRED、REQUIRES_NEW 等) |
isolation | 隔离级别(如 READ_COMMITTED、REPEATABLE_READ 等) |
rollbackFor | 指定哪些异常类型触发回滚(默认只回滚 RuntimeException) |
readOnly | 是否为只读事务(如用于查询优化) |
timeout | 设置事务超时时间(秒) |
五、事务生效的前提和常见坑点
- 类必须被 Spring 容器管理,且注解方法必须被代理调用(即非内部方法调用)
- 方法必须是
public
,否则事务注解不会生效(默认 JDK 动态代理) - 异常必须是未被捕获的运行时异常才会触发回滚(或用
rollbackFor
明确指定)
六、总结面试话术
Spring 提供了编程式和声明式两种事务管理方式,其中声明式事务通过 AOP 实现,核心是 TransactionInterceptor 拦截业务方法,并配合事务管理器 PlatformTransactionManager 控制事务的开启、提交和回滚。开发中常使用注解
@Transactional
来声明事务行为,是企业级开发中必备机制。