【mybatis源码分析(四)】mybatis事务实现原理

Mybatis管理事务分为三种方式:

mybatis的Transaction接口

  1. JdbcTransaction:使用JDBC的事务管理机制,利用java.sql.Connection对象完成事务的提交。
  2. ManagedTransaction:使用Managed的事务管理机制,mybatis自身不会去实现事务管理,而是让容器(JBOSS、WebLogic)实现对事务的管理。
  3. SpringManagedTransaction:使用spring的事务管理机制,利用@Transaction注解即可实现

有于现在都是基于springboot的项目了,所以就只分析SpringManagedTransaction

先了解一些接口和类

1、TransactionSynchronization接口是Spring的事务扩展接口,是一个回调接口,用于在事务执行过程中的重要时间点执行额外的逻辑,

2、TransactionSynchronizationManager类:使用ThreadLocal管理当前事务的TransactionSynchronization集合

3、ResourceHolderSynchronization类:是用来同步资源的(Spring事务中资源的概念),例如:JDBC中的Connection,Hibernate的Session、JPA的EntiyManager、kafka的Producer。

在mybatis中,SqlSessionUtil类内部类SqlSessionSynchronization继承了TransactionSynchronizationAdapter适配器类(等于实现了TransactionSynchronization接口


 

事务执行过程

一、mybatis事务注册过程

1、从SqlSessionTemplate类创建JDK动态代理类开始,因为无论那种执行sql的方式,最终都会走此代码。

2、直接看SqlSessionInterceptor的invoke方法

可以看到先获取sqlsession,然后通过反射调sqlsession的某个方法,最后满足某种条件才commit提交事务

3、进入getSqlSession方法

从事务同步管理器中拿资源(sqlSessionHolder只把是Sqlsession包装了一层),从sessionHolder中拿sqlsesison。

如果没有sqlsession,则通过sessionFacory创建sqlsession,然后执行registerSessionHolder注册sessionHolder。

4、进入registerSessionHoler方法

先判断Configuration配置类中Evironment环境类中的TransactionFactory事务工厂是不是SpringManagedTransactionFactory或其子类。(springboot环境下,默认是)

包装好SqlSessionHolder,然后向TransactionSynchronizationManager中绑定资源和注册TransactionSynchronization

在springboot中构建SqlSessionFactory时,设置了事务工厂为SpringManagedTransactionFactory。

5、最终把TransactionSynchronization注册到了TransactionSynchronizationManager类的synchronizations静态属性中去了。

二、spring事务动态代理过程

springboot项目,为什么我们使用@Transaction注解到service的方法上就能生效?spring底层是如何实现的?

这就要从@EnableTransactionManagement注解开始说起

1、springboot项目的autoconfig包中已经注解了EnableTransactionManagement

2、EnableTransactionManagement注解Import了TransactionManagementConfigurationSelector类,在spring容器初始化是会把此类加载到容器。

3、由于TransactionManagementConfigurationSelector类实现了ImportSelector接口,所以spring容器把返回值的这两个类加入容器

ProxyTransactionManagementConfiguration类主要用于注册和配置BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource、TransactionInterceptor这三个类

4、继续看AutoProxyRegistrar类,它实现了ImportBeanDefinitionRegistrar接口

所以它会执行registerBeanDefinitions方法,用于注册BeanDefinition。

5、其中有个方法registerAutoProxyCreatorIfNecessary,用于注册InfrastructureAdvisorAutoProxyCreator类

只不过它的注册Bean的方式使用了直接new RootBeanDefinition的方式,也是向spring容器注入InfrastructureAdvisorAutoProxyCreator类

6、InfrastructureAdvisorAutoProxyCreator类又实现了BeanPostProcessor接口

用于在bean的初始化的前后对bean做处理,所以会执行postProcessBeforeInitialization方法,用于在bean实例化之前做处理

aop代理肯定是在原bean初始化之后去做,在原bean的基础上增加一次代理包装。

7、wrapIfNecessary方法,如果有必要则创建Proxy代理

8、createProxy方法用于创建动态代理,并返回

三、spring(mybatis)事务执行过程

1、TransactionInterceptor为事务方法拦截执行器,实现了MethodInterceptor接口

2、当调用注解@Transaction的方法时,会执行TransactionInterceptor的invoke方法,因为该方法的类已经被aop代理了。

3、进入invokeWithTransaction方法

TransactionAttribute:为事务相关信息。如注解型事务,看方法获取类上有没有注解@Transactional

PlatformTransactionManager:为事务管理器

TransactionInfo:为事务信息。里面包含事务管理器和事务相关信息

proceedWithInvocation:为调用真正被代理对象service的方法

4、调用真正被代理对象service的方法之后,要进行commitTransactionAfterReturning提交事务

5、进入到事务管理器类的commit方法

6、进入processCommit方法

triggerBeforeCommit:用于触发TransactionSynchronization类的beforeCommit方法

triggerBeforeCompletion:用于触发TransactionSynchronization类的beforeCompletion方法

doCommit:用于spring事务的提交

7、进入TransactionSynchronizationUtils方法进行回调一开始保存在synchronizations属性中的TransactionSynchronization实现类

比如mybaits一开始定义的SqlSessionSynchronization类

8、进入mybatis的SqlSessionSynchronization类的beforeCommit方法

从sqlSessionHolder中取出sqlSesion,执行commit方法提交事务

完毕

猜你喜欢

转载自blog.csdn.net/sumengnan/article/details/114229703