1. 程式人生 > >spring的傳播行為和隔離級別

spring的傳播行為和隔離級別

尼瑪,痛苦死我了。最近打電話問我的都是這個鳥玩意兒,好久沒有搞SSH了,更別說還記得spring的這些。在兩年前,可能我還記得,現在真的不記得了,別人問我的時候,我以為傳播行為和隔離級別我還以為是一個東西,真是醜出大了。現在好好的整理下。參考了:http://blog.chinaunix.net/u1/55983/showart_2091761.html

spring的傳播行為一共有7種:

        1.PROPAGATION_REQUIRED

             支援當前事務,如果當前沒有事務,就新建一個事務。假如當前正要執行的事務不在另外一個事務裡,那麼就起一個新的事務。例如:

          ServiceB.

methodB的事務級別定義為PROPAGATION_REQUIRED, 那麼由於執行ServiceA.methodA的時候, ServiceA.methodA已經起了事務,這時呼叫ServiceB.methodB,ServiceB.methodB看到自己已經執行在ServiceA.methodA 的事務內部,就不再起新的事務。而假如ServiceA.methodA執行的時候發現自己沒有在事務中,他就會為自己分配一個事務。 這樣,在ServiceA.methodA或者在ServiceB.methodB內的任何地方出現異常,事務都會被回滾。即使ServiceB.methodB的事務已經被提交,但是ServiceA.
methodA在接下來fail要回滾,ServiceB.methodB也要回滾。

        2.PROPAGATION_SUPPORTS

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

        3.PROPAGATION_MANDATORY

           支援當前事務,如果當前沒有事務,就丟擲異常。必須在一個事務中執行。也就是說,他只能被一個父事務呼叫。否則,他就要丟擲異常

        4.PROPAGATION_REQUIRES_NEW

           新建事務,如果當前存在事務,把當前事務掛起。比如我們設計ServiceA.methodA的事務級別為PROPAGATION_REQUIRED,ServiceB.

methodB的事務級別為     PROPAGATION_REQUIRES_NEW, 那麼當執行到ServiceB.methodB的時候,ServiceA.methodA所在的事務就會掛起,ServiceB.methodB會起一個新的事務,等ServiceB.methodB的事務完成以後, 他才繼續執行。他與PROPAGATION_REQUIRED 的事務區別在於事務的回滾程度了。因為ServiceB.methodB是新起一個事務,那麼就是存在
兩個不同的事務。如果ServiceB.methodB已經提交,那麼ServiceA.methodA失敗回滾,ServiceB.methodB是不會回滾的。如果ServiceB.methodB失敗回滾, 如果他丟擲的異常被ServiceA.methodA捕獲,ServiceA.methodA事務仍然可能提交。

        5.PROPAGATION_NOT_SUPPORTED

           以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。 比如ServiceA.methodA的事務級別是PROPAGATION_REQUIRED ,而ServiceB.methodB的事務級別是PROPAGATION_NOT_SUPPORTED , 那麼當執行到ServiceB.methodB時,ServiceA.methodA的事務掛起,而他以非事務的狀態執行完,再繼續ServiceA.methodA的事務。

        6.PROPAGATION_NEVER

          以非事務方式執行,如果當前存在事務,則丟擲異常。假設ServiceA.methodA的事務級別是PROPAGATION_REQUIRED, 而ServiceB.methodB的事務級別是PROPAGATION_NEVER , 那麼ServiceB.methodB就要丟擲異常了。

        7.PROPAGATION_NESTED

          如果一個活動的事務存在,則執行在一個巢狀的事務中. 如果沒有活動事務, 則按PROPAGATION_REQUIRED 屬性執行。Nested的事務和他的父事務是相依的,他的提交是要等和他的父事務一塊提交的。也就是說,如果父事務最後回滾,他也要回滾的。 而Nested事務的好處是他有一個savepoint。
*****************************************
ServiceA {

/**
* 事務屬性配置為 PROPAGATION_REQUIRED
*/

void methodA() {
try {
//savepoint

ServiceB.methodB(); //PROPAGATION_NESTED 級別

} catch (SomeException) {
// 執行其他業務, 如 ServiceC.methodC();

}
}

}
********************************************
也就是說ServiceB.methodB失敗回滾,那麼ServiceA.methodA也會回滾到savepoint點上,ServiceA.methodA可以選擇另外一個分支,比如 ServiceC.methodC,繼續執行,來嘗試完成自己的事務。

spring的隔離級別有四種:

1.Serializable

     最嚴格的級別,事務序列執行,資源消耗最大;

2.REPEATABLE READ

    保證了一個事務不會修改,已經由另一個事務讀取但未提交(回滾)的資料。避免了“髒讀取”和“不可重複讀取”的情況,但是帶來了更多的效能損失。

3.READ COMMITTED

   大多數主流資料庫的預設事務等級,保證了一個事務不會讀到,另一個並行事務已修改但未提交的資料,避免了“髒讀取”。該級別適用於大多數系統。

4.Read Uncommitted

  保證了讀取過程中不會讀取到非法資料。隔離級別在於處理多事務的併發問題。