Spring 事务执行流程深度解析
Spring 事务执行流程是一个精心设计的复杂过程,涉及多个组件的协同工作。本文将深入剖析从方法调用到事务完成的完整执行链条,结合核心源码展示实现细节。
一、整体执行流程概览
二、核心阶段深度解析
1. 代理拦截阶段(AOP 拦截器)
核心类:TransactionInterceptor
public class TransactionInterceptor extends TransactionAspectSupport
implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ?
AopUtils.getTargetClass(invocation.getThis()) : null);
// 核心事务处理方法
return invokeWithinTransaction(
invocation.getMethod(),
targetClass,
new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
}
);
}
}
2. 事务属性解析阶段
核心类:AnnotationTransactionAttributeSource
public class AnnotationTransactionAttributeSource
extends AbstractTransactionAttributeSource {
protected TransactionAttribute findTransactionAttribute(Method method) {
// 解析方法上的@Transactional注解
Transactional transactional = AnnotatedElementUtils.findMergedAnnotation(
method, Transactional.class);
if (transactional != null) {
// 转换为事务属性对象
return parseTransactionAnnotation(transactional);
}
return null;
}
protected TransactionAttribute parseTransactionAnnotation(Transactional ann) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
// 设置传播行为
rbta.setPropagationBehavior(ann.propagation().value());
// 设置隔离级别
rbta.setIsolationLevel(ann.isolation().value());
// 设置超时时间
rbta.setTimeout(ann.timeout());
// 设置只读属性
rbta.setReadOnly(ann.readOnly());
// 设置回滚规则
// ...
return rbta;
}
}
3. 事务创建/挂起阶段
核心类:AbstractPlatformTransactionManager
public abstract class AbstractPlatformTransactionManager
implements PlatformTransactionManager {
public final TransactionStatus getTransaction(
TransactionDefinition definition) throws TransactionException {
// 1. 获取当前事务对象
Object transaction = doGetTransaction();
// 2. 处理传播行为
if (isExistingTransaction(transaction)) {
// 存在事务:根据传播行为处理
return handleExistingTransaction(definition, transaction);
}
// 3. 创建新事务
return startTransaction(definition, transaction);
}
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction) {
// REQUIRES_NEW 传播行为处理
if (definition.getPropagationBehavior() ==
TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
// 挂起当前事务
SuspendedResourcesHolder suspendedResources = suspend(transaction);
// 创建新事务
return startTransaction(definition, transaction, suspendedResources);
}
// NESTED 传播行为处理
if (definition.getPropagationBehavior() ==
TransactionDefinition.PROPAGATION_NESTED) {
// 创建保存点
Object savepoint = createSavepoint();
return new NestedTransactionStatus(
transaction, true, savepoint);
}
// 其他传播行为处理...
}
private TransactionStatus startTransaction(TransactionDefinition definition,
Object transaction) {
// 设置超时时间
if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
applyTimeout(definition);
}
// 开启事务
doBegin(transaction, definition);
// 初始化事务状态
return prepareTransactionStatus(
definition,
transaction,
true, // 是否新事务
false, // 是否有保存点
false, // 是否只读
null // 挂起资源
);
}
}
4. 目标方法执行阶段
核心类:ReflectiveMethodInvocation
public class ReflectiveMethodInvocation implements ProxyMethodInvocation {
public Object proceed() throws Throwable {
// 执行拦截器链
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 执行目标方法
return invokeJoinpoint();
}
// 执行下一个拦截器
Object interceptor =
this.interceptorsAndDynamicMethodMatchers.get(this.currentInterceptorIndex++);
return ((MethodInterceptor) interceptor).invoke(this);
}
protected Object invokeJoinpoint() throws Throwable {
// 反射调用业务方法
return AopUtils.invokeJoinpointUsingReflection(
this.target, this.method, this.arguments);
}
}
5. 异常处理与事务回滚
核心类:TransactionAspectSupport
public abstract class TransactionAspectSupport implements BeanFactoryAware {
protected void completeTransactionAfterThrowing(
TransactionInfo txInfo, Throwable ex) {
if (txInfo != null && txInfo.hasTransaction()) {
// 判断是否需要回滚
if (txInfo.transactionAttribute.rollbackOn(ex)) {
try {
// 执行回滚操作
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
} catch (TransactionSystemException ex2) {
// 记录日志或处理异常
}
} else {
try {
// 提交事务(不回滚)
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
} catch (TransactionSystemException ex2) {
// 处理提交异常
}
}
}
}
}
6. 事务提交阶段
核心类:AbstractPlatformTransactionManager
public final void commit(TransactionStatus status) throws TransactionException {
// 检查是否已经完成
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"事务已完成,不应再次提交");
}
// 默认实现处理提交
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
if (defStatus.isLocalRollbackOnly()) {
// 标记为只回滚的事务
processRollback(defStatus, false);
return;
}
// 全局回滚标记检查
if (defStatus.isGlobalRollbackOnly()) {
processRollback(defStatus, true);
return;
}
// 执行提交
processCommit(defStatus);
}
private void processCommit(DefaultTransactionStatus status) {
try {
// 前置提交处理
prepareForCommit(status);
triggerBeforeCommit(status);
// 嵌套事务处理
if (status.hasSavepoint()) {
// 释放保存点
status.releaseHeldSavepoint();
} else if (status.isNewTransaction()) {
// 新事务提交
doCommit(status);
} else if (isFailEarlyOnGlobalRollbackOnly()) {
// 全局回滚检查
}
// 提交后处理
triggerAfterCommit(status);
} finally {
// 清理资源
cleanupAfterCompletion(status);
}
}
三、关键场景下的执行流程
场景 1:嵌套事务 (PROPAGATION_NESTED)
场景 2:REQUIRES_NEW 传播行为
四、高级特性分析
1. 事务同步器 (TransactionSynchronization)
在事务生命周期中插入自定义逻辑:
public class AuditTransactionSynchronization implements TransactionSynchronization {
@Override
public void suspend() {
// 事务挂起时执行
}
@Override
public void resume() {
// 事务恢复时执行
}
@Override
public void beforeCommit(boolean readOnly) {
// 提交前执行(仍可访问事务资源)
}
@Override
public void beforeCompletion() {
// 提交/回滚前执行(事务资源已关闭)
}
@Override
public void afterCommit() {
// 提交成功后执行
}
@Override
public void afterCompletion(int status) {
// 最终完成时执行(包括回滚)
}
}
// 注册同步器
TransactionSynchronizationManager.registerSynchronization(
new AuditTransactionSynchronization());
2. 事务资源管理
资源绑定原理:
// 获取数据库连接(自动绑定到当前事务)
Connection conn = DataSourceUtils.getConnection(dataSource);
// 实际获取连接的核心代码
public static Connection doGetConnection(DataSource dataSource) throws SQLException {
// 1. 尝试从当前事务获取连接
ConnectionHolder conHolder = (ConnectionHolder)
TransactionSynchronizationManager.getResource(dataSource);
if (conHolder != null && conHolder.hasConnection()) {
return conHolder.getConnection();
}
// 2. 新建连接并绑定到事务
Connection newCon = dataSource.getConnection();
if (TransactionSynchronizationManager.isSynchronizationActive()) {
// 绑定到当前事务
ConnectionHolder holderToUse = new ConnectionHolder(newCon);
TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
}
return newCon;
}
3. 只读事务优化
实现原理:
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager {
@Override
protected void prepareTransactionalConnection(
Connection con, TransactionDefinition definition) throws SQLException {
if (definition.isReadOnly()) {
// 设置数据库连接为只读模式
con.setReadOnly(true);
}
// 为Hibernate等ORM框架设置只读提示
if (definition.isReadOnly() && this.prepareConnection) {
Integer prevIsolation = null;
try {
prevIsolation = con.getTransactionIsolation();
con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
} catch (Throwable ex) {
// 回滚设置
}
}
}
}
五、性能优化关键点
1. 事务超时实现
public abstract class AbstractPlatformTransactionManager {
protected void applyTimeout(TransactionDefinition definition) {
// 获取当前线程
Thread thread = Thread.currentThread();
// 创建超时监控线程
Thread monitor = new Thread(() -> {
try {
Thread.sleep(definition.getTimeout() * 1000);
// 超时后中断事务线程
thread.interrupt();
} catch (InterruptedException ignored) {}
});
monitor.setDaemon(true);
monitor.start();
}
}
2. 最小化事务范围
优化建议:
- 避免在事务中进行复杂计算
- 将数据库操作放在事务最后
- 使用延迟加载优化
3. 批量操作优化
@Transactional
public void batchProcess(List<Item> items) {
int batchSize = 100;
int count = 0;
for (Item item : items) {
// 批量提交
if (++count % batchSize == 0) {
flushAndClear(); // 手动刷新会话
}
processItem(item);
}
}
private void flushAndClear() {
entityManager.flush(); // 提交当前批次
entityManager.clear(); // 清空一级缓存
}
六、疑难问题解决方案
1. 自调用事务失效问题
解决方案:
@Service
public class OrderService {
// 注入自身代理实例
@Autowired
private ApplicationContext context;
private OrderService selfProxy() {
return context.getBean(OrderService.class);
}
public void createOrder(Order order) {
// 通过代理调用内部方法
selfProxy().processPayment(order);
}
@Transactional
public void processPayment(Order order) {
// 事务处理逻辑
}
}
2. 分布式事务协调
Saga模式实现:
@Service
public class OrderSagaCoordinator {
@Transactional
public void createOrder(Order order) {
// STEP 1: 创建订单
orderService.create(order);
// STEP 2: 扣减库存
try {
inventoryService.deductStock(order);
} catch (Exception e) {
// 补偿操作
orderService.cancel(order.getId());
throw e;
}
// STEP 3: 创建支付
try {
paymentService.createPayment(order);
} catch (Exception e) {
// 补偿操作
inventoryService.restock(order);
orderService.cancel(order.getId());
throw e;
}
}
}
七、总结与最佳实践
Spring 事务执行流程的核心在于:
- 代理拦截机制:通过 AOP 动态代理拦截事务方法
- 事务属性解析:将注解转换为可执行的事务规则
- 传播行为处理:根据不同传播行为决定事务的创建/挂起策略
- 资源绑定机制:确保同一事务使用相同的资源连接
- 异常处理体系:基于配置规则决定回滚或提交
最佳实践建议:
- 显式指定事务属性:始终明确设置传播行为、隔离级别等
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, timeout = 30)
- 合理使用只读事务:对查询操作启用只读模式
@Transactional(readOnly = true)
- 精细化控制回滚:明确指定回滚异常类型
@Transactional(rollbackFor = BusinessException.class)
- 避免大事务:拆分业务逻辑,减少事务持有时间
- 监控事务性能:关注事务执行时间和并发性能
理解 Spring 事务的完整执行流程,可以帮助开发者:
- 高效排查事务相关问题
- 设计高性能的事务方案
- 实现复杂的事务逻辑
- 构建可靠的分布式事务
- 优化系统整体事务性能
通过深入源码层面的分析,开发者可以超越简单的注解使用,真正掌握 Spring 事务框架的精髓,从而构建出更加健壮高效的企业级应用。