欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > Spring声明式事务@Transaction源码全链路逐行剖析:关键文件、类、方法与流程分支详解

Spring声明式事务@Transaction源码全链路逐行剖析:关键文件、类、方法与流程分支详解

2025/5/24 4:09:35 来源:https://blog.csdn.net/weixin_39863120/article/details/148134857  浏览:    关键词:Spring声明式事务@Transaction源码全链路逐行剖析:关键文件、类、方法与流程分支详解

下面我将以Spring声明式事务(@Transactional)处理流程为主线,对每个关键环节进行源码文件、类、方法、行级字段/变量、关键判断、流程分支的详细剖析,力求做到“源码逐行、注释逐段、全链路还原”,让你彻底掌握Spring事务的底层运行机制。


一、AOP代理生成与事务增强切入

1.1 Bean创建时生成AOP代理

源码位置

  • 文件:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.java
  • 方法:wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {// 检查是否已增强if (beanName != null && this.targetSourcedBeans.contains(beanName)) {return bean;}// 判断是否需要代理(如含@Transactional)if (shouldSkip(bean.getClass(), beanName)) {return bean;}// 获取需要应用的Advisor(如事务增强器)Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);if (specificInterceptors != DO_NOT_PROXY) {// 创建代理对象(JDK/CGLIB)Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));return proxy;}return bean;
}

关键点

  • shouldSkip判定是否需要AOP增强
  • getAdvicesAndAdvisorsForBean查找Advisor(如TransactionAttributeSourceAdvisor
  • 走到createProxy,最终生成代理对象

1.2 方法调用进入AOP拦截链

源码位置

  • 文件:org.springframework.aop.framework.CglibAopProxy.java
  • 内部类:DynamicAdvisedInterceptor
  • 方法:intercept
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {// 1. 获取拦截器链List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);if (chain.isEmpty()) {// 2. 没有拦截器直接调用目标方法return methodProxy.invoke(target, args);} else {// 3. 有拦截器时,进入CglibMethodInvocationreturn new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}
}

关键点

  • getInterceptorsAndDynamicInterceptionAdvice返回所有拦截器(增强器)
  • TransactionInterceptor就是其中之一

二、事务拦截器TransactionInterceptor源码剖析

2.1 拦截器主流程

源码位置

  • 文件:org.springframework.transaction.interceptor.TransactionInterceptor.java
  • 方法:invoke
public Object invoke(final MethodInvocation invocation) throws Throwable {// 1. 获取事务属性(如传播、回滚规则等)TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);// 2. 选择事务管理器PlatformTransactionManager tm = determineTransactionManager(txAttr);// 3. 方法标识String joinpointIdentification = methodIdentification(method, targetClass, txAttr);// 4. 创建/加入事务TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);Object retVal;try {// 5. 进入下一个拦截器或目标业务代码retVal = invocation.proceedWithInvocation();} catch (Throwable ex) {// 6. 异常处理(回滚判定)completeTransactionAfterThrowing(txInfo, ex);throw ex;} finally {// 7. 清理ThreadLocalcleanupTransactionInfo(txInfo);}// 8. 正常提交commitTransactionAfterReturning(txInfo);return retVal;
}

关键点

  • getTransactionAttributeSource()返回AnnotationTransactionAttributeSource,解析@Transactional属性
  • determineTransactionManager确定使用哪个事务管理器(比如DataSourceTransactionManager)
  • createTransactionIfNecessary涉及传播行为决策

三、事务传播行为源码全链路剖析

3.1 创建/获取事务对象

源码位置

  • 文件:org.springframework.transaction.interceptor.TransactionAspectSupport.java
  • 方法:createTransactionIfNecessary
protected TransactionInfo createTransactionIfNecessary(PlatformTransactionManager tm, TransactionAttribute txAttr, String joinpointIdentification) {if (txAttr != null && tm != null) {// 关键:调用事务管理器的getTransaction,进入传播行为分支TransactionStatus status = tm.getTransaction(txAttr);return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);}// ...
}

关键点

  • tm.getTransaction(txAttr)直接进入事务传播行为源码

3.2 传播行为分支源码

源码位置

  • 文件:org.springframework.transaction.support.AbstractPlatformTransactionManager.java
  • 方法:getTransaction
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {Object transaction = doGetTransaction(); // 1. 获取当前线程事务资源(如ConnectionHolder)if (isExistingTransaction(transaction)) {// 2. 已有事务,分支处理return handleExistingTransaction(definition, transaction, debugEnabled);}// 3. 无事务,分支处理if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {throw new IllegalTransactionStateException(...);}if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {// 创建新事务return startTransaction(definition, transaction, debugEnabled, null);}// NOT_SUPPORTED、NEVER、SUPPORTS:非事务性执行return prepareTransactionStatus(definition, null, true, false, debugEnabled, null);
}

关键点

  • isExistingTransaction判断当前线程是否已经有事务
  • 不同传播行为分支明确

3.3 已有事务下的传播行为分支

源码位置

  • 文件:同上
  • 方法:handleExistingTransaction
private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled) throws TransactionException {switch (definition.getPropagationBehavior()) {case TransactionDefinition.PROPAGATION_NEVER:throw new IllegalTransactionStateException(...);case TransactionDefinition.PROPAGATION_NOT_SUPPORTED:Object suspendedResources = suspend(transaction);return prepareTransactionStatus(definition, null, false, false, debugEnabled, suspendedResources);case TransactionDefinition.PROPAGATION_REQUIRES_NEW:Object suspendedResources = suspend(transaction);try {return startTransaction(definition, transaction, debugEnabled, suspendedResources);} catch (RuntimeException | Error beginEx) {resumeAfterBeginException(transaction, suspendedResources, beginEx);throw beginEx;}case TransactionDefinition.PROPAGATION_NESTED:if (!isNestedTransactionAllowed()) {throw new NestedTransactionNotSupportedException(...);}DefaultTransactionStatus status = prepareTransactionStatus(...);status.createAndHoldSavepoint();return status;default:// REQUIRED、SUPPORTS、MANDATORY:加入现有事务return prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);}
}

关键点

  • 挂起、保存点、抛异常等操作均有专门分支
  • suspend/resume用于REQUIRES_NEW、NOT_SUPPORTED
  • createAndHoldSavepoint用于NESTED

四、事务挂起/恢复/保存点行级剖析

4.1 挂起事务

源码位置

  • 文件:同上
  • 方法:suspend
protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) {if (transaction != null) {doSuspend(transaction); // 释放当前事务资源(如ConnectionHolder)}List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();// ...保存SuspendedResourcesHolder
}

4.2 恢复事务

源码位置

  • 文件:同上
  • 方法:resume
protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder) {if (resourcesHolder != null) {doResume(transaction, resourcesHolder.suspendedResources);}doResumeSynchronization(resourcesHolder.suspendedSynchronizations);
}

4.3 嵌套事务保存点

源码位置

  • 文件:同上
  • 方法:DefaultTransactionStatus#createAndHoldSavepoint
public void createAndHoldSavepoint() throws TransactionException {this.savepoint = getSavepointManager().createSavepoint();
}

五、事务提交、回滚与异常判定

5.1 回滚判定

源码位置

  • 文件:org.springframework.transaction.interceptor.TransactionAspectSupport.java
  • 方法:completeTransactionAfterThrowing
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {if (txInfo != null && txInfo.getTransactionStatus() != null) {if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());} else {txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());}}
}

关键点

  • 回滚与否由rollbackOn方法决定

5.2 回滚规则决策

源码位置

  • 文件:org.springframework.transaction.interceptor.DefaultTransactionAttribute.java
  • 方法:rollbackOn
public boolean rollbackOn(Throwable ex) {return (ex instanceof RuntimeException || ex instanceof Error);
}

关键点

  • 只对运行时异常和Error回滚

自定义规则:

  • 文件:RuleBasedTransactionAttribute.java
  • 方法:rollbackOn
public boolean rollbackOn(Throwable ex) {RollbackRuleAttribute winner = null;int deepest = Integer.MAX_VALUE;if (this.rollbackRules != null) {for (RollbackRuleAttribute rule : this.rollbackRules) {int depth = rule.getDepth(ex);if (depth >= 0 && depth < deepest) {deepest = depth;winner = rule;}}}if (winner == null) {return super.rollbackOn(ex);}return !(winner instanceof NoRollbackRuleAttribute);
}

六、事务管理器具体实现

6.1 JDBC事务管理(DataSourceTransactionManager)

源码位置

  • 文件:org.springframework.jdbc.datasource.DataSourceTransactionManager.java
  • 方法:doBegin
protected void doBegin(Object transaction, TransactionDefinition definition) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;Connection con = DataSourceUtils.getConnection(this.dataSource); // 获取连接con.setAutoCommit(false); // 关闭自动提交,开启事务txObject.setConnectionHolder(new ConnectionHolder(con), true); // 绑定到当前线程// 处理隔离级别、只读等
}

关键点

  • 绑定Connection到当前线程,保证同一线程的数据库操作共用一个事务。

七、设计模式源码体现

  • 代理模式:AOP代理生成(AbstractAutoProxyCreator#createProxyCglibAopProxy/JdkDynamicAopProxy
  • 责任链模式:AOP拦截器链(CglibAopProxy.DynamicAdvisedInterceptor#intercept
  • 模板方法模式AbstractPlatformTransactionManager定义流程、子类实现细节
  • 策略模式PlatformTransactionManager多实现(如DataSource/JPA/JTA)
  • 适配器模式:各持久化框架适配Spring事务接口
  • 装饰器/观察者模式TransactionSynchronizationManager扩展事务事件能力

八、常见误区源码定位

8.1 内部方法调用事务失效

源码本质

  • 事务增强依靠AOP代理,内部调用(this.)不会经过代理,无法增强。

九、结语

每一个事务传播行为、每一次回滚判定、每一步资源挂起/恢复,Spring事务体系都在源码中给出了清晰的分支与实现
理解这些源码细节,才能做到知其然,更知其所以然,在实际开发与排查问题时游刃有余。


十、参考资料

  • TransactionInterceptor.java
  • TransactionAspectSupport.java
  • AbstractPlatformTransactionManager.java
  • DataSourceTransactionManager.java
  • Spring官方事务文档

如需某一传播行为的全链路源码跟踪、更细粒度的设计模式变体分析或具体调试/断点演示,可继续追问!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词