Spring事物傳播級別NESTED和REQUIRES_NEW的區別

今天在看Spring事務的處理,注意到了傳播級別這個參數,一共是以下幾個值

REQUIRED(0),
SUPPORTS(1),
MANDATORY(2),
REQUIRES_NEW(3),
NOT_SUPPORTED(4),
NEVER(5),
NESTED(6);

其他幾種不用多說,詳細可以戳這里,主要是結合自己的分析,感覺網上說到REQUIRES_NEWNESTED的區別時,描述大都不太準確,所以做下記錄
先看如下代碼

class A {
    public void invoke() {
        try {
            new B().invoke();
        catch (Exception e) {
            new C().invoke();
        }
        // 此處可能還有其他業務代碼
        ...
    };
}

class B {
    public void invoke() {};
}

class C {
    public void invoke() {};
}

不論使用REQUIRES_NEW或是NESTED,在調用B的invoke時如果發生異常,都能正確完成業務邏輯

  • REQUIRES_NEW執行到B時,A事物被掛起,B會新開了一個事務進行執行,B發生異常后,B中的修改都會回滾,然后外部事物繼續執行
  • NESTED執行到B時,會創建一個savePoint,如果B中執行失敗,會將數據回滾到這個savePoint

重點來了,如果B處正常執行,就會產生區別了

  • REQUIRES_NEW如果B正常執行,則B中的數據在A提交之前已經完成提交,其他線程已經可見其修改,這就意味著可能有臟數據的產生;同時,如果接下來A的其他邏輯發生了異常,A回滾,但是B已經完成提交,不會回滾了。當然,如果A接下來的邏輯沒有相關要求,那就無所謂了
  • NESTED如果B正常執行,此時B中的修改并不會立即提交,而是在A提交時一并提交,如果A下面的邏輯中發生異常,A回滾時,B中的修改也會回滾,就可以避免上述情況的發生
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容