spring事务的底层实现流程
2022-07-26 15:14:37 0 举报
spring事务底层实现原理
作者其他创作
大纲/内容
创建TransactionStatus对象子流程
PROPAGATION_REQUIRES_NEW
会把当前事务的一些信息设置到TransactionSynchronizationManager中
@EnableTransactionManagement工作原理:使用@EnableTransactionManagement注解来开启Spring事务是,该注解代理的功能就是向Spring容器中添加了两个Bean:1. AutoProxyRegistrar2. ProxyTransactionManagementConfigurationAutoProxyRegistrar主要的作用是向Spring容器中注册了一个InfrastructureAdvisorAutoProxyCreator的Bean。而InfrastructureAdvisorAutoProxyCreator继承了AbstractAdvisorAutoProxyCreator,所以这个类的主要作用就是开启自动代理的作用,也就是一个BeanPostProcessor,会在初始化后步骤中去寻找Advisor类型的Bean,并判断当前某个Bean是否有匹配的Advisor,是否需要利用动态代理产生一个代理对象。ProxyTransactionManagementConfiguration是一个配置类,它又定义了另外三个bean:1. BeanFactoryTransactionAttributeSourceAdvisor:一个Advisor2. AnnotationTransactionAttributeSource:相当于BeanFactoryTransactionAttributeSourceAdvisor中的Pointcut3. TransactionInterceptor:相当于BeanFactoryTransactionAttributeSourceAdvisor中的AdviceAnnotationTransactionAttributeSource就是用来判断某个类上是否存在@Transactional注解,或者判断某个方法上是否存在@Transactional注解的。TransactionInterceptor就是代理逻辑,当某个类中存在@Transactional注解时,到时就产生一个代理对象作为Bean,代理对象在执行某个方法时,最终就会进入到TransactionInterceptor的invoke()方法。
创建事务子流程
触发同步器的beforeCommit
如果有则把挂起的事务重新设置到TransactionSynchronizationManager中去,并执行同步器的resume()方法
查看@Transactional注解上是否指定了TransactionManager,如果没有指定,则默认获取TransactionManager类型的bean作为TransactionManager
如果是其他值则会在当前事务中运行
调用suspend()方法将当前事务对象进行挂起,并返回suspendedResources对象
代理对象执行方法时
doBegin()
设置数据库连接的autoCommit为false
判断是否有事务挂起
触发同步器的afterCompletion()
创建事务成功后执行业务方法
TransactionSynchronizationManager中包括了很多ThreadLocal,用来记录当前线程中事务的各种信息,比如事务的名字、事务对象、事务的隔离级别等,所以我们也可以通过TransactionSynchronizationManager在业务代码中来获取事务的一些状态
PROPAGATION_NESTED
如果执行业务方法出现异常,则会进行回滚,然后执行完finally中的方法后再将异常抛出
判断传播机制
构造一个TransactionStatus
默认情况下为RuntimeException或Error会回滚
触发同步器的afterCommit
获取当前正在执行的方法上的@Transactional注解的信息TransactionAttribute
不持有就表示当前线程中不存在事务
回滚事务子流程
调用数据库连接对象的rollback()
将PlatformTransactionManager、TransactionAttribute、TransactionStatus构造成为一个TransactionInfo对象,并返回TransactionInfo对象
其他
但是不包含事务对象,也不会去建立数据库连接
调用数据库连接对象的commit()
需要回滚
如果本次开启事务当前线程第一次开启事务,那么获得的事务对象中 则没有只有数据库连接对象如果本次开启事务时当前线程中还有事务没有提交,那么获得的事务对象中就拥有数据库连接对象
TransactionAspectSupport#methodIdentification
判断获得的事务对象中是否持有数据库连接对象
doBegin的子流程
设置当前数据库连接的隔离级别
开始创建事务
判断当前异常是否需要回滚
如果事务对象中没有持有数据库连接对象,那么则调用DataSource获取一个数据库连接对象,并设置到事务对象中去
抛异常
PROPAGATION_REQUIRE
持有就表示当前线程中存在事务
不需要回滚则提交
触发同步器的beforeCompletion()
设置数据库连接的timeout
PROPAGATION_NEVER
生成一个joinpointIdentification,作为事务的名字
把获得的数据库连接对象通过TransactionSynchronizationManager设置到当前线程的ThreadLocal中
返回Spring容器中类型为TransactionManager的Bean对象TransactionAspectSupport#determineTransactionManager
调用AbstractPlatformTransactionManager类中的getTransaction(txAttr)方法,实际上这个方法就是真正去开启事务的方法
得到一个TransactionStatus对象
构造并返回TransactionStatus对象,TransactionStatus对象中存在suspendedResources,并且更新TransactionSynchronizationManager中的信息
提交子流程
PROPAGATION_MANDATORY
如果执行业务方法没有出现异常,那么则会执行完finally中的方法后再进行提交
TransactionAspectSupport#invokeWithinTransaction
加了@Transactional注解的类,或者类中拥有@Transactional注解的方法,都会生成代理对象作为bean
不持有
这个比较简单,就是利用数据库连接对象,设置一个savepoint,比如mysql就支持,在一个事务中,可以在某个位置设置一个savepoint,后续可以只回滚到某个savepoint
Spring事务基本执行原理:一个Bean在执行Bean的创建生命周期时,会经过InfrastructureAdvisorAutoProxyCreator的初始化后的方法,会判断当前当前Bean对象是否和BeanFactoryTransactionAttributeSourceAdvisor匹配,匹配逻辑为判断该Bean的类上是否存在@Transactional注解,或者类中的某个方法上是否存在@Transactional注解,如果存在则表示该Bean需要进行动态代理产生一个代理对象作为Bean对象。该代理对象在执行某个方法时,会再次判断当前执行的方法是否和BeanFactoryTransactionAttributeSourceAdvisor匹配,如果匹配则执行该Advisor中的TransactionInterceptor的invoke()方法,执行基本流程为:1. 利用所配置的PlatformTransactionManager事务管理器新建一个数据库连接2. 修改数据库连接的autocommit为false3. 执行MethodInvocation.proceed()方法,简单理解就是执行业务方法,其中就会执行sql4. 如果没有抛异常,则提交5. 如果抛了异常,则回滚
PROPAGATION_NOT_SUPPORTED如果当前存在事务,则把当前事务挂起,然后以非事务的方式运行
对于TransactionManager有一个限制,必须是PlatformTransactionManager
收藏
收藏
0 条评论
下一页