Spring事務控制(PROPAGATION_NESTED)


轉載於:https://blog.csdn.net/z69183787/article/details/76208998
在 SPRING 中一共定義了六種事務傳播屬性

PROPAGATION_REQUIRED -- 支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

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

PROPAGATION_MANDATORY -- 支持當前事務,如果當前沒有事務,就拋出異常。

PROPAGATION_REQUIRES_NEW -- 新建事務,如果當前存在事務,把當前事務掛起。

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

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

PROPAGATION_NESTED -- 如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。

最容易弄混淆的其實是PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED

PROPAGATION_REQUIRES_NEW 啟動一個新的, 不依賴於環境的 "內部" 事務. 這個事務將被完全

commited 或 rolled back 而不依賴於外部事務,它擁有自己的隔離范圍, 自己的鎖, 等等.

當內部事務開始執行時, 外部事務將被掛起, 內務事務結束時, 外部事務將繼續執行.

PROPAGATION_REQUIRES_NEW常用於日志記錄,或者交易失敗仍需要留痕

另一方面, PROPAGATION_NESTED 開始一個 "嵌套的" 事務, 它是已經存在事務的一個真正

的子事務. 潛套事務開始執行時, 它將取得一個 savepoint.

如果這個嵌套事務失敗, 我們將回滾到此 savepoint. 潛套事務是外部事務的一部分,

只有外部事務結束后它才會被提交.

由此可見, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大區別在於,

PROPAGATION_REQUIRES_NEW 完全是一個新的事務, 而 PROPAGATION_NESTED

則是外部事務的子事務, 如果外部事務 commit, 潛套事務也會被 commit,

這個規則同樣適用於 roll back.

幾個例子理解REQUIRED、REQUIRES_NEW、NESTED 的使用注意事項(TRY...CATCH配合使用)

1、REQUIRED的使用注意項

1.1 REQUIRED保證其處理過程同一個事務,如果調用的同一個類的配置的REQUIRED的方法,且此方法存在TRY CATCH

代碼塊, 如果此代碼塊出現異常,程序可以繼續執行。

1.2 但如果調用的其他類的配置REQUIRED方法,且TRY CATCH住,則全部的提交全部回滾,且報出異常:

Transaction rolled back because it has been marked as rollback-only

因為事務報出異常后要全部回滾,包括父類的調用。

1.3 如果service中包含多個dao的方法,其都屬於同一個事務,其中報錯全部回滾,try catch住不影響程序代碼的繼續執行.

class A{

//PROPAGATION_REQUIRED

 void methodA() {

    try{

      methodB(); //可以繼續執行,因為是同一個類

    }catch(Exception ex){

      ex.printStrace();

    }

    

    try{

      methodC(); //報錯Transaction rolled back because it has been marked as rollback-only

                 //因為回滾整個事務,不能用try catch住.當然通過不會try catch一個事務的部分代碼

    }catch(Exception ex){

      ex.printStrace();

    }

}

//PROPAGATION_REQUIRED

void methodB() {

}

}

class B{

//PROPAGATION_REQUIRED

void methodC() {

}

}

2、NESTED的具體用途如下:

在此方法出現異常時,通過TRY CATCH 代碼塊包含住, 繼續往下執行或者執行CATCH中的處理.

此點REUQIRED做不到, REQUIRED_NEW能做到, 但它是單獨的事務,不與父類一塊提交的。

ServiceA {

/**

  • 事務屬性配置為 PROPAGATION_REQUIRED

*/

void methodA() {

try {

//savepoint

ServiceB.methodB(); //PROPAGATION_NESTED 級別

} catch (SomeException) {

// 執行其他業務, 如 ServiceC.methodC();

}}}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM