@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:
- 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/349713.html
標籤:其他
上一篇:Feign遠程呼叫模塊業務方法
