spring 事务源码分析
2024-05-08 13:19:17 0 举报
结合AOC分析spring源码中事务的处理过程
作者其他创作
大纲/内容
获得TransactionAttribute
同aop流程
computeTransactionAttribute
find
传播行为PROPAGATION_MANDATORY
N
TransactionInterceptor#invoke
传播行为PROPAGATION_REQUIRED或PROPAGATION_REQUIRES_NEW或PROPAGATION_NESTED
doBegin和原来一样
通过getTransactionAttribute看是否有@Transactional注解
解析为hashMap
JdkDynamicAopProxy#invoke
通知的大致两种转换方式:1.通过适配器2.advice本身实现了Intercepter
N其它几种事务都不需要开启事务
return true匹配成功
super.findCandidateAdvisors()
解析出来的就是这个
String[] advisorNames = this.cachedAdvisorBeanNames;
开启一个新事务
获取一个数据库Connection封装到ConnectionHolder中
从ThreadLocal中获取
(PayService) context.getBean(\"payServiceImpl\")
空事务
传播行为NOT_SUPPORTED
Y
转换效果
解析成真正的事务属性对象return parseTransactionAnnotation(attributes);
加入到缓存,下次直接从缓存中拿
根据当前接口IPayService解析@Transactional
this.advisorRetrievalHelper.findAdvisorBeans()
根据当前类的方法解析@Transactional
是否存在
createTransactionIfNecessary
AopUtils#canApply
applyBeanPostProcessorsAfterInitialization
设置ConnectionHolder
将提取的结果加入缓存中
事务advisor解析
1.去父类上找2.去接口上找
AbstractFallbackTransactionAttributeSource#getTransactionAttribute
0
得到事务属性
加入事务的描述属性中
创建事务
实现
当获得被代理的bean时实际获取的是动态代理对象
NOT_SUPPORTED挂起事务,自己不开启事务
DataSourceTransactionManager#doBegin
是否被解析只会解析一次后续缓存
((Calculate)AopContext.currentProxy())
不代理equals方法不代理hashCode方法不代理DecoratingProxy方法不代理Advised方法
最终会调用InfrastructureAdvisorAutoProxyCreator
挂起的事务SuspendedResourcesHolder
currentInterceptorIndex=-1
ReflectiveMethodInvocation#proceed
isExistingTransaction是否存在事务
chain.isEmpty()
将事务激活状态、隔离级别、是否只读、事务名称、事务激活绑定到TransactionSynchronizationManager
当前方法是否为接口
解析exposeProxy属性
如果转化不了空
忽略
获取当前的拦截器++this.currentInterceptorIndex
DefaultAdvisorAdapterRegistry#getInterceptors
创建一个事务状态DefaultTransactionStatus
创建动态代理
挂起已经存在的事务suspend
调用基于jdk动态代理
从容器获得所有类型为Advisor的beanName
加入缓存
advisor会优先创建BeangetBean()
解析注解
AbstractPlatformTransactionManager#handleExistingTransaction
postProcessAfterInitialization
没有就转换
isCurrentlyInCreation?
AbstractAutowireCapableBeanFactory#initializeBean
存在则证明是嵌套事务Y
根据事务切点匹配器匹配命中的方法TransactionAttributeSourcePointcut#matches
融入原事务
根据当前接口的方法(pay) 解析@Transactional
适配的advice
类/方法
获得TransactionAttributeSource
传播行为NEVER
其实就是将外层事务信息全部缓存在TransactionSynchronizationManager中然后干掉了原来事务的ConnectionHolder,变成了一个空事务
遍历所有的advisorNames
getAdvicesAndAdvisorsForBean
return advisors;
return trueY
findAdvisorsThatCanApply
调用被代理的方法
调用代理
advisorNames
for
全部转化为拦截器通过责任链模式调用
递归出口:调用到了最后一个拦截器
名字是否符合
设置readOnly和事务隔离级别
1.去桥接方法上找2.去接口对应的方法上找3.去父类对应的方法上找
抛出异常
MethodCacheKey cacheKey = new MethodCacheKey(method);List<Object> cached = this.methodCache.get(cacheKey);
解析切面
缓存中有直接返回
con.setAutoCommit(false);
searchWithFindSemantics匹配大致分为几种:
设置到ThreadLocal
是否超时
设置事务名称
当前类或者元素上是否有@Transactional注解
获取事务状态TransactionStatusPlatformTransactionManagerFacade#getTransaction
调用动态代理类的invoke方法
advice本身实现了Intercepter
获取最终实现方法
缓存当前方法是否解析过
getInterceptorsAndDynamicInterceptionAdvice
获得PlatformTransactionManager事务管理器,配置类中包含数据源
类
传播行为NESTED
传播行为REQUIRES_NEW
直接调用
方法
@Override protected boolean isEligibleAdvisorBean(String beanName) { /** * 容器中包含了这个bean的定义,并且bean定义的角色为 BeanDefinition.ROLE_INFRASTRUCTURE */ return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) && this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE); }
非嵌套事务:第一次ConnectionHolder是空的,所以不存在事务,ConnectionHolder会在后续的doBegin中设置嵌套事务:第一次后ConnectionHolder已存在说明是嵌套事务
未被解析if (advisorNames == null)
绑定数据源和ConnectionHolder到同步管理器
this.cachedAdvisorBeanNames = advisorNames;
payService.pay(\"123456789\
第一次父事务肯定不存在N
1
根据当前类解析@Transactional
获取一个事务对象(关键看有没有ConnectionHolder)
开启新事物
符合
从缓存中拿
TransactionInterceptor#invoke#invokeWithinTransaction
0 条评论
下一页