@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为例子@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的时候 很明确的表明了这个观点;
它的作用主要是向Spring容器中添加了两个Bean:
- AutoProxyRegistrar
- 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欢迎分享,转载请注明来源:内存溢出
评论列表(0条)