声明式事务 源码解析

声明式事务 源码解析


先看总结把。

一、声明式事务-环境搭建:

导入pom.xml中的

image-20200612130049434

image-20200612130058400

spring-jdbc来简化数据库操作

image-20200612132618457

image-20200612132639835

在这里注意:Spring对@Configuration类会特殊处理;给容器中加组件的方法,多次调用都只是从容器中找组件

来一个service来操作

image-20200612135224955

dao

image-20200612135148058

测试:

当然此时在@Configuration中得把这些组件都扫描进来

image-20200612135537759

image-20200612135658615

image-20200612135645245

插入成功。这个方法是没有事务的。我们来模拟一个错误

image-20200612135935744

在这里后面加一个异常

我们发现出现了异常

image-20200612140020281

但还是插入进去了

image-20200612140037334

* 1、导入相关依赖
*     数据源、数据库驱动、Spring-jdbc模块
* 2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据

二、声明式事务-测试成功

比如如果insert这个方法中任何一步出现问题,都会回滚

image-20200612141141589

只需要加上@Transactional,就表明这是一个事务方法。spring在执行这个方法的时候就会进行事务控制。如果说出现异常,所有操作都会进行回滚

首先我们刚刚看了数据库中有3条记录

image-20200612141422909

现在我们使用@Transactional

image-20200612141504159

image-20200612141519955

发现数据库中还是出现了,这说明我们的事务没有加上

要开启事务还需要做以下操作:

@EnableTransactionManagement

开启事务管理功能

image-20200612141852311

我们发现,报了这个异常

image-20200612141925388

No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available

告诉我们还没有配事务管理器

image-20200612142231280

image-20200612142343091

image-20200612142405871

点击运行

image-20200612142523021

还是这么多条,说明加上事务了

* 4@EnableTransactionManagement 开启基于注解的事务管理功能;
*     @EnableXXX
* 5、配置事务管理器来控制事务;
*     @Bean
*     public PlatformTransactionManager transactionManager()

三、声明式事务-原理分析

我们来看一下这个注解 @EnableTransactionManagement为什么可以开启事务呢?

image-20200612142815191

我们以前学习过这个ImportSelector,

image-20200612142908250

image-20200612142935892

image-20200612143024937

可以看到我们的@EnableTransactional中的mode默认是

image-20200612143118894

PROXY

所以它会来给我们容器中导入这两个组件: AutoProxyRegistrarProxyTransactionManagementConfiguration

image-20200612143229411

那么这个AutoProxyRegistrar 就是来给我们容器中注册bean的

image-20200612143322305

是这么来注册的

image-20200612143515760

又因为proxyTargetClass是默认false

image-20200612143611144

image-20200612143706879

自动代理创建器

image-20200612143745352

传了一个InfrastructureAdvisorAutoProxyCreator

我们可以看见下面有一个大家熟悉的

image-20200613122308799

这在aop里面有讲。

只是我们事物这里导的是

image-20200613122359220

之前aop是一个后置处理器

image-20200613122517402

我们发现它这里也是,所以我们就来看一下它的作用:
image-20200613122750568

利用后置处理器机制在对象创建后,包装对象,返回一个代理对象(增强器),代理对象执行方法,利用拦截器链进行调用

可以看见它的父类的父类

image-20200613123254289

就是找各种增强器来进行封装

image-20200613123325685

bean完成创建之后还是来这里包装

6.那么 ProxyTransactionManagementConfiguration又做了什么呢?

它第一个来给容器中注册组件

第一个叫做 transactionAdvisor,事务增强器

它在注册的时候需要一个事务属性

image-20200613123620380

事务属性又是一个容器中的bean

image-20200613123648215

事务属性也是调用了一个annotation,我们将这个annotation点过来

image-20200613123746086

一个this(boolean)的构造器

image-20200613124024963

annotationParsers注解解析器

SPringTransactionAnnotationParser spring transaction的解析器

JtaTransactionAnnotationParser jta transaction的解析器

Ejb3TransactionAnnotationParser ejb3 transaction的解析器

image-20200613124106349

可以看见,就是来解析我们transactional注解中的每一个信息

这里除了注解里面的信息,还有一个transaction拦截器。事务拦截器

image-20200613124248689

这里创建了一个transactionIntercepter

image-20200613124407161

它把这个transactional属性和transactionMannager也保存起来

image-20200613124507826

8.我们可以去看看这个transactionIntercepter是什么

image-20200613124603003

它有一个MethodInterceptor,这是我们aop里面说过的

我们aop里面四个通知方法都被弄成增强器,增强器再被弄为MethodInterceptor

它是一个方法拦截器。

即我们要给容器中放一个代理对象,代理对象要执行目标方法了,拦截器就会进行工作。怎么工作呢?

这里有一个 invokeWithinTransaction

image-20200613124902409

利用事务进行工作

image-20200613125010733

先获取 事务的属性, 再来 获取 transactionManager

再目标方法执行的时候,跟我们之前aop原理一模一样。因为它是代理对象在执行,代理对象在执行的时候,会来执行拦截器链,拦截器链就是它,这个MethodInterceptor,而这个拦截器只有一个,就是TransactionInterceptor。

我们来看它的执行:

1.获取事务相关的属性

2.再获取PlatformTransactionManager。这个怎么获取呢,我们之前给容器放了一个,我们点进来看看怎么获取?

image-20200613125416615

image-20200613130819846

image-20200613130629903

但是我们通常不指定,所以来到else

image-20200613130853828

它就从ioc容器中,按照类型获取的。获取到了,就能直接用了。

10.我们来看他第三步的执行

image-20200613131200048

它来得到这些要执行事务的方法

image-20200613131328916

相当于事务方法执行

image-20200613131401231

11.它是这么的

image-20200613131620494

先来创建一个事务

事务如果出现异常

image-20200613131705437

image-20200613131723546

它是拿到事务管理器进行回滚

所以真正的回滚是事务管理器来做的

image-20200613131836512

如果没有异常:

image-20200613131954859

image-20200613132020762

我们顺便看一下上面的getTransaction

image-20200613132122193

四、总结

image-20200613132540994

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章