Spring 的事务管理是其核心功能之一,通过 声明式事务 和 编程式事务 两种方式实现。其底层原理基于 AOP(面向切面编程) 和 动态代理,结合事务管理器(PlatformTransactionManager)控制事务边界,确保数据一致性。
🧠 一、事务实现的核心机制
1. 基于 AOP 的声明式事务
@Transactional
注解标记的方法会被 Spring AOP 拦截,生成代理对象。- 代理对象在方法执行前后插入事务逻辑(开启、提交、回滚)。
2. 事务的线程绑定
- Spring 使用 ThreadLocal 将事务绑定到当前线程,确保同一事务内共享数据库连接。
- 避免多线程下事务冲突,但需注意线程池或异步调用时的事务传播问题。
3. 事务管理器接口(PlatformTransactionManager)
- 定义事务的基本操作:
getTransaction()
、commit()
、rollback()
。 - 常见实现:
DataSourceTransactionManager
(单数据源)JtaTransactionManager
(分布式事务)HibernateTransactionManager
(Hibernate 集成)
🔄 二、事务处理流程(关键步骤)
1. 启用事务:@EnableTransactionManagement
- 导入
ProxyTransactionManagementConfiguration
,注册事务相关的切面和代理工厂。 - 创建事务拦截器(
TransactionInterceptor
)和事务顾问(BeanFactoryTransactionAttributeSourceAdvisor
)。
2. 生成代理对象
- Spring 使用 JDK 动态代理(接口方法)或 CGLIB 代理(子类继承)生成目标类的代理。
- 代理类拦截
@Transactional
方法,调用 TransactionInterceptor.invoke()
。
3. 事务拦截器(TransactionInterceptor)
- 核心方法
invokeWithinTransaction()
:protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) {TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);PlatformTransactionManager tm = determineTransactionManager(txAttr);TransactionStatus status = tm.getTransaction(txAttr);try {Object result = invocation.proceedWithInvocation();tm.commit(status);return result;} catch (Throwable ex) {tm.rollback(status);throw ex;}
}
📦 三、事务传播行为(Propagation Behavior)
行为 | 说明 |
---|
REQUIRED | 默认行为。当前有事务则加入,无事务则新建 |
REQUIRES_NEW | 总是新建事务,挂起已有事务 |
SUPPORTS | 支持当前事务,无事务则以非事务执行 |
NOT_SUPPORTED | 不支持事务,以非事务执行 |
MANDATORY | 必须存在事务,否则抛异常 |
NEVER | 不能存在事务,否则抛异常 |
NESTED | 嵌套事务,外层事务回滚会影响内层 |
🔐 四、事务隔离级别(Isolation Level)
级别 | 脏读 | 不可重复读 | 幻读 | 实现方式 |
---|
DEFAULT | 由数据库决定 | - | - | - |
READ_UNCOMMITTED | ✅ | ✅ | ✅ | 最低隔离 |
READ_COMMITTED | ❌ | ✅ | ✅ | Oracle 默认 |
REPEATABLE_READ | ❌ | ❌ | ✅ | MySQL 默认 |
SERIALIZABLE | ❌ | ❌ | ❌ | 最高隔离 |
⚠️ 五、事务失效的常见场景(含源码级原因)
1. 方法非 public
- Spring AOP 默认只拦截 public 方法(JDK 动态代理限制)。
- 解决:改为 public 方法,或启用 AspectJ 代理。
2. 内部调用(Self-invocation)
- 同一类中调用
@Transactional
方法时,代理失效。@Service
public class MyService {public void outerMethod() {innerMethod(); }@Transactionalpublic void innerMethod() { ... }
}
- 解决:通过注入自身 Bean 调用:
@Autowired
private MyService self;public void outerMethod() {self.innerMethod();
}
3. 未正确配置事务管理器
- 缺少
PlatformTransactionManager
Bean。 - 解决:显式配置事务管理器(如
DataSourceTransactionManager
)。
4. 异常未触发回滚
🧱 六、事务与 AOP 的关系
组件 | 作用 |
---|
TransactionInterceptor | 事务切面,拦截方法并控制事务 |
TransactionAttributeSource | 解析 @Transactional 注解,获取事务属性 |
TransactionAspectSupport | 提供事务处理的基础支持 |
ProxyFactory | 创建动态代理(JDK/CGLIB) |
📊 七、Spring Boot 中的事务自动装配
Spring Boot 通过 @EnableTransactionManagement
自动启用事务支持,并根据依赖自动配置事务管理器:
- 如果存在单数据源 → 注册
DataSourceTransactionManager
- 如果存在 JTA → 注册
JtaTransactionManager
配置示例(application.properties):
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=123456
spring.jpa.hibernate.ddl-auto=update
✅ 总结
特性 | Spring 事务实现 |
---|
实现方式 | AOP + 动态代理 |
事务边界 | ThreadLocal 管理线程上下文 |
传播行为 | 7 种行为,控制事务嵌套关系 |
隔离级别 | 5 种级别,控制并发数据一致性 |
失效场景 | 方法非 public、内部调用、异常未触发回滚等 |
事务管理器 | PlatformTransactionManager 接口实现 |