Spring原理篇(16)--Spring事务的实现;

@TOC# Spring系列
记录在程序走的每一步___auth:huf


连载Spring 源码系列 将近2个多月; Spring快要结束了. 随后应该会更新 Spring的另外一个模块. SpringMVC 它是可以单独运行的;他是基于 Servlet 而扩展来的.基于MVC 模式 进行演化.之前考虑先讲struts2 跟 Hibernate 但是这两个框架现在用得比较少 Hibernate还行. 但是struts2 的话. 已经过时了. 我们当初使用struts 到struts2 到 SpringMVC无缝整合 到现在SpringBoot的;从单体应用 但现在的SpringCloud 一整套应用 到SpringCloud 大部分应用停更 又是一套解决方案学习的时间 学习还是得有一条路线;所以决定先讲Spring mvc 然后Mybatis 然后继续往SpringBoot 及其他分布式组件的源码讲解; 也有同学想听以下并发. 或者 JDK原理的 也会陆陆续续的更新; 喜欢的同学记得三连. 大家一起进步 一起学习;为祖国贡献出一份自己的力量;


在此之前需要引入相对应的Maven配置 这里就不再累赘

我们要知道 我们在程序执行sql的时候 我们是怎么去连接数据库的 这里以Mysql为例子

/**
 * auth:huf
 */
@SpringBootApplication
public class TestMain {
    
    
    public static void main(String[] args) throws Exception {
    
    
        ConfigurableApplicationContext run = SpringApplication.run(TestMain.class, args);
		"加载驱动"
        Class.forName("com.mysql.jdbc.Driver");
        " 创建数据库连接"
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC",
                "root", "123456");
        "执行sql"        
        Statement statement = conn.createStatement();
        boolean execute = statement.execute("INSERT INTO student (id,student_name) VALUES ('1','1')");
         "得到结果"
        ResultSet rs = ps.executeQuery();
		"忽略关闭数据库 操作.."
    }
}

这就是我们普通连接数据库并且执行的语句;这样如果在保存成功之后 发生了错误.那么 数据已经持久化在数据库中了 这时候就会比较麻烦 我们怎么办?

 Connection conn = DriverManager.getConnection(...);
 conn.setAutoCommit(false);
 "执行sql" 
 "手动提交"
 conn.commit();

Spring Transactional 就是帮我们做了这么一件事情;
我们把JdbcTemplate 交给Spring管理;

接下来我们开始进入今天的主题

Transactional

在我们的方法中 我们只要加入了@Transactional 注解 代表着我们已经对这个方法里面执行的所有sql开启了事务;

为什么我会在AOP 讲解之后讲 Spring Transactional; 因为它就是基于Spring AOP来实现的;
Spring 开启事务 本质上就是 增加了一个Advisor 一个Advisor 是由一个Advice 和一个 Pointcut构成的.
这个在之前AOP的时候 很明确的表明了这个观点;

@EnableTransactionManagement 原理

它的作用主要是向Spring容器中添加了两个Bean:

  1. AutoProxyRegistrar
  2. ProxyTransactionManagementConfiguration

AutoProxyRegistrar:主要的作用是向Spring容器中注册了一个 InfrastructureAdvisorAutoProxyCreator的Bean。 而InfrastructureAdvisorAutoProxyCreator 继承了AbstractAdvisorAutoProxyCreator,所以这个类的主要作用就是开启自动代理的作用,也 就是一个BeanPostProcessor,会在初始化后步骤中去寻找Advisor类型的Bean,并判断当前某个 Bean是否有匹配的Advisor,是否需要利用动态代理产生一个代理对象。

ProxyTransactionManagementConfiguration 主要作用是定义了三个Bean :

1.BeanFactoryTransactionAttributeSourceAdvisor; 看结尾就很容易看出来 是一个Advisor;
2.AnnotationTransactionAttributeSource:相当于 上面那个Advisor中的Pointcut
3.TransactionInterceptor:相当于BeanFactoryTransactionAttributeSourceAdvisor中的 Advice

记忆顺序 1,2,3 木头人

(一)EnableTransactionManagement 注册   (二)AutoProxyRegistrar 和  (二)ProxyTransactionManagementConfiguration
(二)AutoProxyRegistrar 注册  (木头人)InfrastructureAdvisorAutoProxyCreator 去开启自动代理 找Advisor类型的Bean. 
(二)ProxyTransactionManagementConfiguration 生成 
BeanFactoryTransactionAttributeSourceAdvisor  ----Advisor
AnnotationTransactionAttributeSource  ---Pointcut
TransactionInterceptor ----Advice

一个注解注册两个bean 一个Bean又创建三个对象 还有一个木头人去找Advisor类型的Bean. 三个对象分别为Advisor Pointcut Advice; Pointcut 去判断 类上 或者方法上是否有@Transactional注解 Advice 在寻找到该切点的时候 执行里面的invoke()方法;


Spring 事务的基本执行原理

当我们的Bean 在初始化过后;就会进过 (木头人) InfrastructureAdvisorAutoProxyCreator 木头人给判断它是否有@Transactional注解.如果有就生成动态代理;

当我们执行代理对象的被代理方法的时候. 就会调用TransactionInterceptor的invoke()方法;

他们两者 都需要经过 BeanFactoryTransactionAttributeSourceAdvisor 进行匹配判断;.

这样 三个对象都解释清楚了


执行流程是:

1.利用所配置的PlatformTransactionManager事务管理器新建一个数据库连接
2.修改数据库连接的autocommit为false
3.执行MethodInvocation.proceed()方法,简单理解就是执行业务方法,其中就会执行sql
4.如果没有抛异常,则提交
5.如果抛了异常,则回滚

然后这样 就跟上面浅水区的 conn.setAutoCommit(false); 相呼应上了


总结:

Spring 事务的原理;

Spring事务的执行过程;

本来作者打算 今晚一篇就全部更新完Spring事务的. 无奈今天太晚. 明天还有生产版本要发布.估计得熬到很晚. 今天就早点结束了 明天还有一个Spring 事务的传播机制; 这个再面试过程中 会经常被问到,而且不容易记住; 看看明天是否又时间给大伙更新完最后的事务传播篇.

seeyou

猜你喜欢

转载自blog.csdn.net/wenaicoo/article/details/121151328