亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Spring 事務中 REQUIRES_NEW 和 NESTED 傳播的行為差異

Spring 事務中 REQUIRES_NEW 和 NESTED 傳播的行為差異

手掌心 2021-12-01 14:57:23
前言首先:它不是Spring 事務中 requires_new 和嵌套傳播之間的差異的重復- 我閱讀了它,但我沒有找到我的問題的答案題:在閱讀我提到的主題后,我明白了物理事務計數中傳播級別之間的主要區別:2 db 事務 -REQUIRES_NEW用于外部和內部方法1 db 事務 -NESTED用于外部和內部方法。如果底層數據庫不支持保存點,它將不起作用但從我的角度來看,邏輯似乎是一樣的。如何理解在實踐中使用哪個級別?任何用例來理解它?行為差異的方便例子?PS我想其他事務的差異有一些可見性,因為不同的事務提交時間。PS2另外我想有性能差異:@Transactionalpublic void outer(){    for(int i=0;i<100500;i++){        inner();    }   }@Transactionalpublic void inner(){   //some logic}對于這種情況,NESTED 會更好,因為 1 個長物理交易而不是 100500+1
查看完整描述

3 回答

?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

就您的示例而言,如果inner()有:


@Transactional(propagation=Propagation.REQUIRES_NEW)

public void inner(){

   //some logic

}

然后,如果它在outer()循環中的第二個調用中拋出異常,則第一個調用中的更改將已經提交 - 由其REQUIRES_NEW.


如果inner()有:


@Transactional(propagation=Propagation.NESTED)

public void inner(){

   //some logic

}

然后將回滾第一次調用的更改 - 因為outer().


傳播級別inner()真正開始重要的一點是outer()循環是否要處理以下異常inner():


@Transactional

public void outer() {

    for (int i = 0; i < 100500; i++) {

        try {

            inner();

        } catch (Exception ex) {

            // Report and continue

        }

    }

    // Something else that could fail

}

顯然,兩者REQUIRES_NEW并NESTED只保留從成功改變inner()通話。但關鍵的區別在于,NESTED如果outer().


正如您所說,另一個因素是可擴展性 - 某些數據庫可能不會通過NESTED傳播來理解父事務的大小。


此外,這可能值得一提——盡管我懷疑它只是為了讓示例更加清晰。this.inner()直接調用是繞過 Spring 事務顧問程序。它需要被允許注入一個“被建議的 bean”,以允許@Transactional注釋在調用之前和之后發揮它的魔力——例如nextAutowiredBean.inner()。


查看完整回答
反對 回復 2021-12-01
?
幕布斯6054654

TA貢獻1876條經驗 獲得超7個贊

我看到的最大差異:

在嵌套的情況下:

  • 如果外部事務回滾,則嵌套的 tra 也會回滾。

  • 可見性:如果數據庫同時執行非常常見的 MVCC,

    • 嵌套的 tra 會看到外部 tra 的先前更改。

    • 在外部提交后,嵌套 tra 的更改將被提交,并且對其他 tra 可見。

  • 性能:請注意,外部事務的工作集會被內部事務擴展。所以更多的鎖,更多的 MVCC 原像存儲,更長的重做日志條目。

在 requires_new 的情況下:

  • 如果外層事務回滾,則外層tra回滾的情況下,內層tra的變化不會回滾。

  • 可見性:對于同時非常常見的 MVCC,

    • 內部 tra 不會看到尚未提交的外部 tra 所做的更改。

    • 在這個內部 tra 提交之后,甚至在外部 tra 提交之前,嵌套 tra 的更改將被提交并立即對其他 tra 可見。鎖更少,但由于提交更多的外部操作,redo-lock 中的記錄更多。

性能方面,如果其他因素不重要,您可以在交易大小和交易數量之間找到收支平衡。如果嵌套的速度比 requires_new 快,那么這個問題沒有通用的答案。


查看完整回答
反對 回復 2021-12-01
?
墨色風雨

TA貢獻1853條經驗 獲得超6個贊

如果您的內部邏輯獨立于外部邏輯,則使用 Requires_new,如果不使用嵌套。

例如,您的外部方法可能正在處理包含大量記錄的作業并調用保持作業狀態(進度、警告和驗證錯誤)的內部方法。您希望內部方法事務是獨立的,并且它的數據庫更改會立即保存,以便系統的其他部分可以顯示進度。如果外部方法遇到異常,它的事務會回滾,但內部方法的事務不會。

當您需要將外部和內部更改同時保留或同時回滾時,您可能希望使用嵌套或依賴事務。例如,您需要創建一個新用戶(使用“外部”服務)并保存他們的地址(使用“內部”服務)。如果您的要求是用戶必須有一個地址,那么如果保存用戶或地址失敗,您希望這兩個更改都回滾。


查看完整回答
反對 回復 2021-12-01
  • 3 回答
  • 0 關注
  • 449 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號