想讓你的應(yīng)用程序更加可靠?來了解Spring事務(wù)的回滾機(jī)制吧!

嗨,大家好,我是小米,今天要和大家聊一聊關(guān)于Spring框架事務(wù)的回滾源碼實(shí)現(xiàn)。
相信對于使用Spring框架的小伙伴來說,事務(wù)管理肯定是非常重要的一個(gè)環(huán)節(jié),事務(wù)的管理不好很容易出現(xiàn)各種問題,如數(shù)據(jù)不一致等。而Spring框架正是為了解決這些問題,提供了非常強(qiáng)大的事務(wù)管理機(jī)制。Spring框架中的事務(wù)機(jī)制是由AOP實(shí)現(xiàn)的,通過代理對象來實(shí)現(xiàn)事務(wù)的控制。在代理對象中,會(huì)按照AOP的整套流程來執(zhí)行具體的操作邏輯,正常情況下要通過通知來完成核心功能,但是事務(wù)不是通過通知實(shí)現(xiàn)的,而是通過一個(gè)TransactionInterceptor來實(shí)現(xiàn)的,然后調(diào)用invoke來實(shí)現(xiàn)具體的邏輯。
那么,Spring框架是如何實(shí)現(xiàn)事務(wù)的回滾呢?下面就讓我們一起來探討一下吧,在具體的實(shí)現(xiàn)中,我們需要按照以下幾個(gè)步驟來完成:

準(zhǔn)備工作
在執(zhí)行具體的操作之前,我們需要先對事務(wù)相關(guān)的屬性進(jìn)行解析,并根據(jù)具體的屬性來判斷是否需要開啟一個(gè)新的事務(wù)。這個(gè)過程是在TransactionAspectSupport類的invokeWithinTransaction方法中完成的。
在這個(gè)方法中,首先會(huì)根據(jù)當(dāng)前的目標(biāo)方法和目標(biāo)類,從緩存中獲取已經(jīng)解析好的事務(wù)信息。如果緩存中不存在,則會(huì)調(diào)用prepareTransactionInfo方法來解析事務(wù)信息。
這個(gè)方法的實(shí)現(xiàn)比較簡單,就是從目標(biāo)方法和目標(biāo)類中解析出相關(guān)的事務(wù)屬性,然后根據(jù)這些屬性來創(chuàng)建一個(gè)TransactionInfo對象,并將其保存到事務(wù)緩存中。需要注意的是,如果當(dāng)前方法不需要開啟事務(wù),則不會(huì)創(chuàng)建TransactionInfo對象,也不會(huì)將其保存到緩存中。
開啟事務(wù)
如果當(dāng)前需要開啟一個(gè)新的事務(wù),則會(huì)通過DataSourceUtils.getConnection方法獲取一個(gè)數(shù)據(jù)庫連接,并將其保存到TransactionInfo對象中。同時(shí),還需要關(guān)閉自動(dòng)提交功能,并開啟事務(wù)。
這個(gè)過程的實(shí)現(xiàn)比較簡單,就是調(diào)用getConnection方法獲取連接對象,然后調(diào)用setAutoCommit方法將其自動(dòng)提交功能關(guān)閉,并調(diào)用setReadOnly方法將其設(shè)為只讀模式。接著,通過調(diào)用getTransaction方法來獲取事務(wù)對象,并調(diào)用beginTransaction方法開啟事務(wù)。
執(zhí)行操作
在事務(wù)開啟之后,就可以開始執(zhí)行具體的操作了。這個(gè)過程是通過調(diào)用代理對象的目標(biāo)方法來完成的。在執(zhí)行目標(biāo)方法之前,會(huì)先檢查當(dāng)前事務(wù)是否已經(jīng)提交或回滾,如果已經(jīng)提交或回滾,則直接返回。
在執(zhí)行目標(biāo)方法的過程中,如果發(fā)生異常,則會(huì)觸發(fā)completeTransactionAfterThrowing方法,這個(gè)方法的主要作用是完成事務(wù)的回滾操作。
回滾事務(wù)
在completeTransactionAfterThrowing方法中,會(huì)首先判斷當(dāng)前事務(wù)是否是新開啟的事務(wù),如果是,則直接將其回滾并關(guān)閉連接。
如果當(dāng)前事務(wù)不是新開啟的事務(wù),則會(huì)根據(jù)當(dāng)前事務(wù)的傳播行為來判斷是否需要回滾。如果需要回滾,則調(diào)用事務(wù)對象的rollback方法回滾事務(wù),并關(guān)閉連接。
需要注意的是,在回滾事務(wù)之前,還需要將當(dāng)前線程綁定的ConnectionHolder對象清空,這個(gè)過程是通過TransactionSynchronizationManager.unbindResource方法來完成的。
提交事務(wù)
在目標(biāo)方法執(zhí)行結(jié)束之后,會(huì)根據(jù)事務(wù)的傳播行為來判斷是否需要提交事務(wù)。如果需要提交事務(wù),則會(huì)調(diào)用事務(wù)對象的commit方法來提交事務(wù),并關(guān)閉連接。
需要注意的是,在提交事務(wù)之前,還需要將當(dāng)前線程綁定的ConnectionHolder對象清空,這個(gè)過程是通過TransactionSynchronizationManager.unbindResource方法來完成的。
后置處理
在事務(wù)提交或回滾之后,還需要進(jìn)行一些后置處理,這個(gè)過程是通過TransactionAspectSupport類中的completeTransactionAfterReturning方法來完成的。
這個(gè)方法會(huì)檢查當(dāng)前事務(wù)是否是新開啟的事務(wù),如果是,則會(huì)調(diào)用cleanupTransactionInfo方法來清空相關(guān)的事務(wù)信息。
同時(shí),還需要將當(dāng)前線程綁定的ConnectionHolder對象清空,這個(gè)過程是通過TransactionSynchronizationManager.unbindResource方法來完成的。
總結(jié)
以上就是Spring框架事務(wù)回滾的主要流程和源碼實(shí)現(xiàn)。需要注意的是,這里只是簡單地介紹了Spring框架事務(wù)回滾的實(shí)現(xiàn)方式,實(shí)際上還有很多細(xì)節(jié)需要考慮,如事務(wù)的傳播行為、事務(wù)的隔離級別等。因此,在實(shí)際的開發(fā)過程中,我們還需要深入了解Spring框架事務(wù)的相關(guān)知識,以保證事務(wù)的正確性和穩(wěn)定性。
END
如有疑問或者更多的技術(shù)分享,歡迎關(guān)注我的微信公眾號“知其然亦知其所以然”!
