1. 程式人生 > >spring事務管理實現原理-原始碼-傳播屬性-工作小結

spring事務管理實現原理-原始碼-傳播屬性-工作小結

本部落格分為兩點,一個是spring事務實現原理原始碼解讀(個人能力,初步解讀),二是spring事務的傳播屬性

 

簡單案例,儲存訂單,修改商品數量

就是這兩個方法,第一個方法中引用了第二個方法,都用@Transactional註解。debug呼叫shopping方法。

 

spring事務實現的原始碼

在呼叫方法時會掃描@Transactional,進入方法前會判斷是否有註解(在類上也會掃描到,具體掃描方式不是本部落格重點)

接著debug這個test方法,會產生proxy的代理

進入proxy(動態代理)

也就是說通過AOP,在進入具體的方法之前,對方法進行了增強,具體增強什麼,看下文。

在這個代理裡面,實際做事情的是這個判斷後的方法(前面都是一些判斷),invocation的proceed()方法;

注:這裡的invocation可以找到真正要呼叫的方法。

點進去看一下,重點是這個,invoke()方法,點進去

注;吐槽下,有的時候看原始碼就是一直點下去,但是不能忘了從哪裡來,和最終目的,可以對著實際程式碼點進去看下,有點頭大了。

繼續點進去看下

好了,這個是重點,這個invokeWithTransaction方法做了很多事情,點進去看下

這個方法createTransactionIfNecessary()等會兒說(在spring的傳播屬性裡面講),看下面的try catch 

你點點點就會到反射到具體的方法,這個時候就會呼叫真正的方法,

所以這個方法已經被增強了,

有了異常會回滾,在catch裡面,而且會throw出去(這裡的丟擲有講究,上家公司就是這麼處理事務的,要求自己對業務進行try catch手動程式設計)。

沒有異常,就走下面的提交(具體的自己點進去看)

這就是大致的spring的事務實現,若有興趣,可看下spring事務的傳播屬性

===========================================================================

spring事務的傳播屬性

好的,上面我說的createTransactionIfNecessary(),在這裡說,

重點是這個接口裡面的getTransaction()方法,很重要,跟進去,去實現裡找到如下:

判斷當前環境是否已經存在事務,有事務走裡面方法,沒有事務走外面繼續走;

繼續走,進行很多判斷,這裡就要說註解@Transactional的資訊,重點關注propagation(傳播行為)和isolation(隔離級別),會有預設值,不同的值會走不同的方法。

這裡就是不同的傳播行為會建立不同的事務,對!事務就是在這裡建立的!

預設是required,會建立事務。如果不使用事務們就會有一個空的事務。

-----------

接下來講測試程式碼的下一行,會進入呼叫程式碼更改數量,此方法也是有事務的,此時會走下圖這裡的標紅框處,因為事務已經存在。

先上圖

這裡就是事務的傳遞了,上面做了總結,

使用當前事務沒啥說的,就是用當前的事務,不建立新的。

重點說下required_new 和 nested(巢狀事務)

nested的話,走判斷,如果可以建立savePoint,那就走巢狀事務,如果不可以,那就走required_new

1 required_new,掛起當前事務,建立新的事務,

required_new事務裡面,回滾就回滾出去了,而且丟擲去的錯(如果此事務被自己catch掉,並且不丟擲,那就另說),會被外層的事務catch到,所以就都回滾了。

2 nested 巢狀事務

nested事務裡面,回滾的話,會回滾到儲存點savePoint,不影響外層事務。而外部事務如果出錯,會影響到巢狀事務,事務會回滾到儲存點。(required_new事務結束就是提交了,nested 事務提交後的儲存點還是有效的,所以會回滾到儲存點)