spring的傳播行為和隔離級別
尼瑪,痛苦死我了。最近打電話問我的都是這個鳥玩意兒,好久沒有搞SSH了,更別說還記得spring的這些。在兩年前,可能我還記得,現在真的不記得了,別人問我的時候,我以為傳播行為和隔離級別我還以為是一個東西,真是醜出大了。現在好好的整理下。參考了:http://blog.chinaunix.net/u1/55983/showart_2091761.html
spring的傳播行為一共有7種:
1.PROPAGATION_REQUIRED
支援當前事務,如果當前沒有事務,就新建一個事務。假如當前正要執行的事務不在另外一個事務裡,那麼就起一個新的事務。例如:
ServiceB.
2.PROPAGATION_SUPPORTS
支援當前事務,如果當前沒有事務,就以非事務方式執行。
3.PROPAGATION_MANDATORY
支援當前事務,如果當前沒有事務,就丟擲異常。必須在一個事務中執行。也就是說,他只能被一個父事務呼叫。否則,他就要丟擲異常
4.PROPAGATION_REQUIRES_NEW
新建事務,如果當前存在事務,把當前事務掛起。比如我們設計ServiceA.methodA的事務級別為PROPAGATION_REQUIRED,ServiceB.
兩個不同的事務。如果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
保證了讀取過程中不會讀取到非法資料。隔離級別在於處理多事務的併發問題。