声明式事务 源码解析
先看总结把。
一、声明式事务-环境搭建:
导入pom.xml中的
spring-jdbc来简化数据库操作
在这里注意:Spring对@Configuration类会特殊处理;给容器中加组件的方法,多次调用都只是从容器中找组件
来一个service来操作
dao
测试:
当然此时在@Configuration中得把这些组件都扫描进来
插入成功。这个方法是没有事务的。我们来模拟一个错误
在这里后面加一个异常
我们发现出现了异常
但还是插入进去了
* 1、导入相关依赖
* 数据源、数据库驱动、Spring-jdbc模块
* 2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
二、声明式事务-测试成功
比如如果insert这个方法中任何一步出现问题,都会回滚
只需要加上@Transactional,就表明这是一个事务方法。spring在执行这个方法的时候就会进行事务控制。如果说出现异常,所有操作都会进行回滚
首先我们刚刚看了数据库中有3条记录
现在我们使用@Transactional
发现数据库中还是出现了,这说明我们的事务没有加上
要开启事务还需要做以下操作:
@EnableTransactionManagement
开启事务管理功能
我们发现,报了这个异常
No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available
告诉我们还没有配事务管理器
点击运行
还是这么多条,说明加上事务了
* 4、 @EnableTransactionManagement 开启基于注解的事务管理功能;
* @EnableXXX
* 5、配置事务管理器来控制事务;
* @Bean
* public PlatformTransactionManager transactionManager()
三、声明式事务-原理分析
我们来看一下这个注解 @EnableTransactionManagement为什么可以开启事务呢?
我们以前学习过这个ImportSelector,
可以看到我们的@EnableTransactional中的mode默认是
PROXY
所以它会来给我们容器中导入这两个组件: AutoProxyRegistrar 、 ProxyTransactionManagementConfiguration
那么这个AutoProxyRegistrar 就是来给我们容器中注册bean的
是这么来注册的
又因为proxyTargetClass是默认false
自动代理创建器
传了一个InfrastructureAdvisorAutoProxyCreator
我们可以看见下面有一个大家熟悉的
这在aop里面有讲。
只是我们事物这里导的是
之前aop是一个后置处理器
我们发现它这里也是,所以我们就来看一下它的作用:
利用后置处理器机制在对象创建后,包装对象,返回一个代理对象(增强器),代理对象执行方法,利用拦截器链进行调用
可以看见它的父类的父类
就是找各种增强器来进行封装
bean完成创建之后还是来这里包装
6.那么 ProxyTransactionManagementConfiguration又做了什么呢?
它第一个来给容器中注册组件
第一个叫做 transactionAdvisor,事务增强器
它在注册的时候需要一个事务属性
事务属性又是一个容器中的bean
事务属性也是调用了一个annotation,我们将这个annotation点过来
一个this(boolean)的构造器
annotationParsers注解解析器
SPringTransactionAnnotationParser spring transaction的解析器
JtaTransactionAnnotationParser jta transaction的解析器
Ejb3TransactionAnnotationParser ejb3 transaction的解析器
可以看见,就是来解析我们transactional注解中的每一个信息
这里除了注解里面的信息,还有一个transaction拦截器。事务拦截器
这里创建了一个transactionIntercepter
它把这个transactional属性和transactionMannager也保存起来
8.我们可以去看看这个transactionIntercepter是什么
它有一个MethodInterceptor,这是我们aop里面说过的
我们aop里面四个通知方法都被弄成增强器,增强器再被弄为MethodInterceptor
它是一个方法拦截器。
即我们要给容器中放一个代理对象,代理对象要执行目标方法了,拦截器就会进行工作。怎么工作呢?
这里有一个 invokeWithinTransaction
利用事务进行工作
先获取 事务的属性, 再来 获取 transactionManager
再目标方法执行的时候,跟我们之前aop原理一模一样。因为它是代理对象在执行,代理对象在执行的时候,会来执行拦截器链,拦截器链就是它,这个MethodInterceptor,而这个拦截器只有一个,就是TransactionInterceptor。
我们来看它的执行:
1.获取事务相关的属性
2.再获取PlatformTransactionManager。这个怎么获取呢,我们之前给容器放了一个,我们点进来看看怎么获取?
但是我们通常不指定,所以来到else
它就从ioc容器中,按照类型获取的。获取到了,就能直接用了。
10.我们来看他第三步的执行
它来得到这些要执行事务的方法
相当于事务方法执行
11.它是这么的
先来创建一个事务
事务如果出现异常
它是拿到事务管理器进行回滚
所以真正的回滚是事务管理器来做的
如果没有异常:
我们顺便看一下上面的getTransaction