Spring事務

Spring AOP原理分析介紹了AOP的一些細節,有了這篇文章的基礎,我們再來分析Spring中聲明式事務的實現就能夠輕車熟路一些。

一些概念

事務可以分爲2種,全局事務與本地事務。

全局事務可以保證多數據源下的事務特性(關於事務的ACID特性這裏不詳說),本地事務則可以保證單個數據源下的事務特性。全局事務使用JTA,支持多事務源事務(通過XA協議來支持,然而XA性能較低,一般都會採取別的分佈式事務方案,比如事務消息,補償方案等);本地事務則基於JDBC連接,不支持分佈式事務。

事務管理器

Spring使用事務管理器來管理事務,下面的接口是Spring事務管理器的統一抽象接口,我們可以根據需要實現自己的事務管理器。Spring提供了許多事務平臺默認的實現,比如基於JDBC的DataSourceTransactionManager,基於JTA的JtaTransactionManager,基於Hibernate的HibernateTransactionManager等。

其中getTransaction(..)方法根據TransactionDefinition參數返回一個TransactionStatus對象。如果當前調用堆棧中存在匹配的事務,則返回的TransactionStatus可能表示一個新事務,也可能表示一個現有事務,由TransactionDefinition來決定。

TransactionDefinition定義了很多常量,代表着不同的含義

以Propagation開頭的代表傳播行爲:在事務範圍內執行的所有代碼都在該事務中運行,但是,如果事務方法在事務上下文已經存在時執行,則可以指定行爲。例如,代碼可以在現有事務中繼續運行(通常情況下),或者可以掛起現有事務並創建一個新事務

以Isolation開頭的代表隔離程度:即事務的隔離級別

getTimeout方法:獲取事務的超時時間

isReadOnly方法(只讀狀態):是否爲只讀狀態

getPropagationBehavior方法:獲取傳播行爲

getIsolationLevel:獲取隔離程度

傳播行爲與隔離級別

由接口中的常量可知,共有7種傳播行爲,分別爲:

REQUIRED:如果當前範圍不存在事務,則新建一個事務(默認)

REQUIRES_NEW:總是新建一個事務。

NESTED:如果當前有事務,則在嵌套事務內執行,如果當前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。僅適用於JDBC事務,本質上是根據JDBC回滾點回滾指定範圍內的操作,NESTED和REQUIRES_NEW都可以做到內部方法事務回滾而不影響外圍方法事務。但是因爲NESTED是嵌套事務,所以外圍方法回滾之後,作爲外圍方法事務的子事務也會被回滾。而REQUIRES_NEW是通過開啓新的事務實現的,內部事務和外圍事務是兩個事務,外圍事務回滾不會影響內部事務

SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行。

MANDATORY:使用當前的事務,如果當前沒有事務,就拋出異常。

NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。

一般情況下我們使用默認的傳播行爲即可。

隔離級別對應的就是數據庫的隔離級別,其中有個DEFAULT,代表着默認的隔離級別,他是跟着底層數據庫變化的,例如如果是MySQL的話,那麼默認的隔離級別就是可重複讀。

聲明式事務

Spring中事務管理分爲編程式事務與聲明式事務,Spring官方建議使用聲明式事務進行事務管理,對代碼侵入性較小。

回滾:默認情況下,Spring只對RunTimeException與Error類型的異常進行回滾,我們也可以指定發生某些異常不會滾或者發生某些異常回滾

聲明式事務使用@Transactional來實現,由於Spring中事務由代理實現,所以AOP的問題事務管理同樣會有:應該只將@Transactional應用於public方法。如果使用@Transactional註釋private,事務並不會生效。在代理模式(這是缺省模式)中,只攔截通過代理傳入的外部方法調用。這意味着自調用(實際上,目標對象中的一個方法調用目標對象的另一個方法)不會在運行時執行事務,即使被調用的方法被標記爲@Transactional。

源碼分析

同Spring AOP一文的分析類似,開啓事務的註解爲@EnableTransactionManagement,從該註解開始分析。

如果是代理模式(默認)則導入AutoProxyRegistrar與ProxyTransactionManagementConfiguration倆個組件。

AutoProxyRegistrar類中最終註冊了InfrastructureAdvisorAutoProxyCreator。

InfrastructureAdvisorAutoProxyCreator是一個後置處理器,我們找到後置處理器相關的接口,在對象創建以後,將對象包裝成代理對象返回

ProxyTransactionManagementConfiguration類註冊了BeanFactoryTransactionAttributeSourceAdvisor與AnnotationTransactionAttributeSource

AnnotationTransactionAttributeSource中的各種TransactionAnnotationParser負責解析事務相應的註解。

另一個bean爲TransactionInterceptor事務攔截器,其中保存了事務的屬性與事務管理器

找到動態代理相關的實現類,查看invoke方法

如果是事務方法則會進入到createTransactionIfNecessary方法開始一個事務,invocation.proceedWithInvocation();執行方法中操作。

如果發生異常則調用completeTransactionAfterThrowing(txInfo, ex);

判斷註解中是否指定了回滾的異常,根據異常做相應的回滾操作

最後調用commitTransactionAfterReturning(txInfo);進行事務的提交。

總結:找到被事務註解註釋的相關bean,爲bean生成代理對象,在對象方法執行時執行代理對象的invoke方法,做相應的事務操作。總體流程和AOP是一樣的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章