spring源碼解析 - spring事務相關源碼分析

前言

上篇咱們分享了Spring AOP的相關源碼,今天咱們分享一個和Spring AOP聯繫很是緊密的話題---Spring事務。不少人認爲事務很簡單,可是每每在工做中遇到一些事務的坑(尤爲是事務方法中嵌套其它事務方法一塊兒使用時)以後,咱們殊不知道問題產生的緣由和如何有效的解決。這就須要去分析Spring的核心源碼,最終踏實地找到問題的緣由和解決思路。spring

註解事務運行流程

先來看Spring事務的底層運行流程
spring源碼解析 - spring事務相關源碼分析編程

核心對象關係

spring源碼解析 - spring事務相關源碼分析
1、事務配置相關
TransactionManagementConfigurationSelector:配置啓動事務啓動(EnableTransactionManagement)時,導入註冊的配置bean。它包括AutoProxyRegistrar和ProxyTransactionManagementConfiguration兩大配置塊。
AutoProxyRegistrar:負責依賴注入事務的相關屬性配置和注入事務入口類(InfrastructureAdvisorAutoProxyCreator類);
ProxyTransactionManagementConfiguration:負責注入事務相關的Bean, 包括:事務切面Bean(BeanFactoryTransactionAttributeSourceAdvisor)、TransactionAttributeSource(事務配置屬性bean)和TransactionInterceptor(事務攔截器bean)等;
2、事務運行攔截相關
AopProxy:Spring AOP 動態代理的基接口,負責定義Proxy的基礎行爲;
MethodInterceptor:Spring AOP調用鏈中攔截器的內部核心接口,全部類型的切面最終都會最終包裝成此接口觸發統一攔截;
TransactionInterceptor:Spring事務攔截器的核心業務實現,AOP調用鏈也最終觸發它的invoke方法;
TransactionManager:Spring管理的基接口,做爲子接口上層接口區分,並無定義實際的事務行爲能力;
PlatformTransactionManager:繼承TransactionManager,定義事務和基礎行爲;
AbstractPlatformTransactionManager:負責實現整個事務管理和運行過程當中的公共行爲和通用實現邏輯,它繼承至PlatformTransactionManager接口;緩存

源碼實現

接下來咱們來分塊分析一下,Spring事務的源碼,其中的一些坑和重要結論會在這個過程分享。
1、事務配置
TransactionManagementConfigurationSelector.selectImports()負責定義外部加入spring容器的配置類
spring源碼解析 - spring事務相關源碼分析
此方法最終在ConfigurationClassParser中被解析並最終實例化爲bean
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析
AutoProxyRegistrar.registerBeanDefinitions()把InfrastructureAdvisorAutoProxyCreator註冊beandefinition
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析
ProxyTransactionManagementConfiguration.transactionAdvisor()注入事務切面
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析ide

2、事務建立
實際運行入口之一(還有cglib):JdkDynamicAopProxy..invoke()
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析
ReflectiveMethodInvocation.proceed()切面調用鏈處理核心方法
spring源碼解析 - spring事務相關源碼分析
TransactionInterceptor.invoke()從這裏觸發事務攔截
spring源碼解析 - spring事務相關源碼分析
TransactionAspectSupport.invokeWithinTransaction()實現Spring事務的核心業務
spring源碼解析 - spring事務相關源碼分析
TransactionAspectSupport.determineTransactionManager()定義指定的事務管理器
spring源碼解析 - spring事務相關源碼分析
對於事務管理器,默認使用DataSourceTransactionManager(可配置數據源的事務管理器),也可自定義事務管理器,而後配置數據源便可。
createTransactionIfNecessary()建立事務信息TransactionInfo:其中包括數據源、事務鏈接(ConnectionHolder)、事務狀態、鏈接緩存等;
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析
DataSourceTransactionManager.doGetTransaction()獲取事務對象:裏面包含鏈接包裝和緩存
spring源碼解析 - spring事務相關源碼分析
TransactionSynchronizationManager.getResource()鏈接線程級緩存:確保當前線程拿到惟一的數據鏈接
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析
AbstractPlatformTransactionManager.startTransaction()開啓一個新事務
spring源碼解析 - spring事務相關源碼分析
只有newTransaction爲true時,spring纔會作實際的提交或回滾,這裏是一個很重要的點。不少嵌套事務的坑,都是這裏沒有理解清楚。
DataSourceTransactionManager.doBegin()開啓事務核心源碼
spring源碼解析 - spring事務相關源碼分析
TransactionSynchronizationManager.bindResource()設置當前鏈接和數據源的線程級綁定
spring源碼解析 - spring事務相關源碼分析
3、事務回滾
對於非編程式事務而言,Spring事務的核心實現其實就是用try / catch 包裹事務提交和回滾的範式而已,但提交和回滾裏面的包裝大有講究。
TransactionAspectSupport.completeTransactionAfterThrowing()事務回滾實現
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析
以上截圖中doSetRollbackOnly(),不會在鏈接上實際設置回滾點,只打個標記(當前事務須要回滾, commit時會使用該標記)!源碼分析

4、事務提交
AbstractPlatformTransactionManager.commit()事務實際提交源碼這裏
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析
cleanupAfterCompletion()回收鏈接或恢復事務,這個點回味無窮:當事務傳播屬性爲Require_New時,會暫時掛起以前的鏈接,而後建立新鏈接;當新鏈接提交或回滾後,經過這個方法恢復以前鏈接和狀態!!!!
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析
spring源碼解析 - spring事務相關源碼分析ui

OK事務到這裏,我根據源碼分享一些關於嵌套子事務的甜點線程

  1. 嵌套事務過程,中間有任何異常,只要沒被屏蔽,則都會上拋,不會再執行後續代碼;
  2. 只要設置Require_New事務傳播屬性,則每一個Transactional註解方法內部都會單獨提交或回滾;
  3. 嵌套事務會在除首個Transactional註解外的子事務中建立savepoint回滾點;
  4. 設置savepoint回滾點後,回滾時會回滾包括當前方法以前的全部事務;若只需回滾當前方法,則在最外層事務方法加try{}catch(){//不拋出異常};
  5. 每一個事務的對象都是不同的,事務狀態可能不同,但鏈接多是同一個;

總結

今天的Spring事務源碼就暫時分享到這裏,事務這塊只有一層的事務很簡單,但當嵌套了多個(層)子事務(並且每一個子事務的事務傳播屬性可能不同的狀況下)時就當另當別論了。須要咱們根據源碼的規律去分析每層子事務該如何流轉!!因此須要把這塊的源碼搞熟,遇到複雜的嵌套事務分析緣由,那問題就不大了。更新spring源碼的乾貨請繼續關注。3d

相關文章
相關標籤/搜索