Spring事务使用
Spring配置事务还是挺简单的,第一步创建事务管理器TransactionManager
,然后在配置中增加一个@EnableTransactionManagement
就可以启用Spring事务了,所以关键类就是@EnableTransactionManagement
1 |
|
我们可以看到@EnableTransactionManagement
上实际上是import了TransactionManagementConfigurationSelector
类,在这个Selector中实际import了
两个配置类:
- AutoProxyRegistrar
- ProxyTransactionManagementConfiguration
1 |
|
下面我们来根据这个入口来分析一下Spring是如何处理事务的:
AutoProxyRegistrar 导入
AutoProxyRegistrar主要的作用是向Spring容器中注册了一个InfrastructureAdvisorAutoProxyCreator的Bean。
这一步位于spring aop包下面的 AopConfigUtils#registerAutoProxyCreatorIfNecessary
方法中
InfrastructureAdvisorAutoProxyCreator
继承了AbstractAdvisorAutoProxyCreator,所以这个类的主要作用就是开启自动代理
的作用,也就是一个BeanPostProcessor
,会在初始化后步骤中去寻找Advisor类型的Bean,并判断当前某个Bean是否有匹配的Advisor,是否需要利用动态代理产生一个代理对象。
这里InfrastructureAdvisorAutoProxyCreator会扫描到事务处理的BeanFactoryTransactionAttributeSourceAdvisor
SpringAOP实现原理
代理对象的生成类是:AbstractAutoProxyCreator
实现了BeanPostProcessor接口,会在Bean初始化完成之后通过postProcessAfterInitialization生成代理对象。
来看postProcessAfterInitialization
方法:
1 | public Object postProcessAfterInitialization( { Object bean, String beanName) |
主要代码就是wrapIfNecessary
, 主要作用是生成Proxy Bean
1 | protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { |
这里 getAdvicesAndAdvisorsForBean
为当前的Bean寻找合适的Advices,这个方法是Abstract方法,因此需要子类去实现。
主要实现代码在AbstractAdvisorAutoProxyCreator
中
1 | protected Object[] getAdvicesAndAdvisorsForBean( |
findEligibleAdvisors 会通过一个工具类在BeanFactory中查合适的Advisor,findAdvisorsThatCanApply会过滤可以被Apply的Advisor, 主要是看目标类和Advisor之间的关系来判断,这里主要由AOP的代码来实现。
ProxyTransactionManagementConfiguration导入
ProxyTransactionManagementConfiguration 是一个配置类,它又定义了另外三个bean:
- BeanFactoryTransactionAttributeSourceAdvisor:一个Advisor
- AnnotationTransactionAttributeSource:相当于
BeanFactoryTransactionAttributeSourceAdvisor
中的Pointcut
- TransactionInterceptor:相当于
BeanFactoryTransactionAttributeSourceAdvisor
中的 Advice
AnnotationTransactionAttributeSource
就是用来判断某个类上是否存在@Transactional注解, 或者判断某个方法上是否存在@Transactional
注解的。TransactionInterceptor
就是代理逻辑,当某个类中存在@Transactional
注解时,到时就产生一个 代理对象作为Bean,代理对象在执行某个方法时,最终就会进入到TransactionInterceptor
的 invoke()
方法。
Spring事务拦截
PlatformTransactionManager
@Transactional处理
Transactional 解析
@Transactional的处理主要是交给TransactionAttributeSourceAdvisor
完成的,TransactionAttributeSourceAdvisor实现了Advisor
接口,因此在Spring创建Bean的时候查找Advisor的时候,只要classpath中有加载到tx相关的jar包,并且Enable相关Transactional的配置了就会执行执行这个Advice增强功能。
TransactionAttributeSourceAdvisor中包含了一个TransactionInterceptor
,也是一个Advice,因此最终 @Transactional
就会最终实现事务的增强功能。
事务执行原理
一个Bean在执行Bean的创建生命周期时,会经过 InfrastructureAdvisorAutoProxyCreator
的初始化后的方法,会判断当前当前Bean对象是否和 BeanFactoryTransactionAttributeSourceAdvisor
匹配。
匹配逻辑为判断该Bean的类上是否存在 @Transactional
注解,或者类中的某个方法上是否存在 @Transactional
注解,如果存在则表示该Bean需要进行动态代理产生一个代理对象作为Bean对象。
该代理对象在执行某个方法时,会再次判断当前执行的方法是否和BeanFactoryTransactionAttributeSourceAdvisor
匹配,如果匹配则执行该Advisor中的 TransactionInterceptor的invoke()方法,执行基本流程为:
- 利用所配置的
PlatformTransactionManager
事务管理器新建一个数据库连接 - 修改数据库连接的
autocommit
为false - 执行
MethodInvocation.proceed()
方法,简单理解就是执行业务方法,其中就会执行sql - 如果没有抛异常,则提交
- 如果抛了异常,则回滚
TransactionInterceptor构造函数传入了一个TransactionManager 来管理事务
1 | public TransactionInterceptor(TransactionManager ptm, TransactionAttributeSource tas) { |
调用Advice的 invoke方法之后最终调用的是父类TransactionAspectSupport的invokeWithinTransaction来进行实际处理
1 | public Object invoke(MethodInvocation invocation) throws Throwable { |