今天在看Spring事務(wù)的處理版确,注意到了傳播級別這個(gè)參數(shù),一共是以下幾個(gè)值
REQUIRED(0),
SUPPORTS(1),
MANDATORY(2),
REQUIRES_NEW(3),
NOT_SUPPORTED(4),
NEVER(5),
NESTED(6);
其他幾種不用多說,詳細(xì)可以戳這里取具,主要是結(jié)合自己的分析,感覺網(wǎng)上說到REQUIRES_NEW
和NESTED
的區(qū)別時(shí)扁耐,描述大都不太準(zhǔn)確暇检,所以做下記錄
先看如下代碼
class A {
public void invoke() {
try {
new B().invoke();
catch (Exception e) {
new C().invoke();
}
// 此處可能還有其他業(yè)務(wù)代碼
...
};
}
class B {
public void invoke() {};
}
class C {
public void invoke() {};
}
不論使用REQUIRES_NEW
或是NESTED
,在調(diào)用B的invoke時(shí)如果發(fā)生異常婉称,都能正確完成業(yè)務(wù)邏輯
-
REQUIRES_NEW
執(zhí)行到B時(shí)块仆,A事物被掛起,B會新開了一個(gè)事務(wù)進(jìn)行執(zhí)行酿矢,B發(fā)生異常后榨乎,B中的修改都會回滾,然后外部事物繼續(xù)執(zhí)行 -
NESTED
執(zhí)行到B時(shí)瘫筐,會創(chuàng)建一個(gè)savePoint蜜暑,如果B中執(zhí)行失敗,會將數(shù)據(jù)回滾到這個(gè)savePoint
重點(diǎn)來了策肝,如果B處正常執(zhí)行肛捍,就會產(chǎn)生區(qū)別了
-
REQUIRES_NEW
如果B正常執(zhí)行,則B中的數(shù)據(jù)在A提交之前已經(jīng)完成提交之众,其他線程已經(jīng)可見其修改拙毫,這就意味著可能有臟數(shù)據(jù)的產(chǎn)生;同時(shí)棺禾,如果接下來A的其他邏輯發(fā)生了異常缀蹄,A回滾,但是B已經(jīng)完成提交膘婶,不會回滾了缺前。當(dāng)然,如果A接下來的邏輯沒有相關(guān)要求悬襟,那就無所謂了 -
NESTED
如果B正常執(zhí)行衅码,此時(shí)B中的修改并不會立即提交,而是在A提交時(shí)一并提交脊岳,如果A下面的邏輯中發(fā)生異常逝段,A回滾時(shí)垛玻,B中的修改也會回滾,就可以避免上述情況的發(fā)生