聲明式事務 源碼解析
先看總結把。
一、聲明式事務-環境搭建:
導入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