3 回答

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超10個(gè)贊
就您的示例而言,如果inner()有:
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void inner(){
//some logic
}
然后,如果它在outer()循環(huán)中的第二個(gè)調(diào)用中拋出異常,則第一個(gè)調(diào)用中的更改將已經(jīng)提交 - 由其REQUIRES_NEW.
如果inner()有:
@Transactional(propagation=Propagation.NESTED)
public void inner(){
//some logic
}
然后將回滾第一次調(diào)用的更改 - 因?yàn)閛uter().
傳播級(jí)別inner()真正開始重要的一點(diǎn)是outer()循環(huán)是否要處理以下異常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()通話。但關(guān)鍵的區(qū)別在于,NESTED如果outer().
正如您所說,另一個(gè)因素是可擴(kuò)展性 - 某些數(shù)據(jù)庫可能不會(huì)通過NESTED傳播來理解父事務(wù)的大小。
此外,這可能值得一提——盡管我懷疑它只是為了讓示例更加清晰。this.inner()直接調(diào)用是繞過 Spring 事務(wù)顧問程序。它需要被允許注入一個(gè)“被建議的 bean”,以允許@Transactional注釋在調(diào)用之前和之后發(fā)揮它的魔力——例如nextAutowiredBean.inner()。

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超7個(gè)贊
我看到的最大差異:
在嵌套的情況下:
如果外部事務(wù)回滾,則嵌套的 tra 也會(huì)回滾。
可見性:如果數(shù)據(jù)庫同時(shí)執(zhí)行非常常見的 MVCC,
嵌套的 tra 會(huì)看到外部 tra 的先前更改。
在外部提交后,嵌套 tra 的更改將被提交,并且對(duì)其他 tra 可見。
性能:請(qǐng)注意,外部事務(wù)的工作集會(huì)被內(nèi)部事務(wù)擴(kuò)展。所以更多的鎖,更多的 MVCC 原像存儲(chǔ),更長(zhǎng)的重做日志條目。
在 requires_new 的情況下:
如果外層事務(wù)回滾,則外層tra回滾的情況下,內(nèi)層tra的變化不會(huì)回滾。
可見性:對(duì)于同時(shí)非常常見的 MVCC,
內(nèi)部 tra 不會(huì)看到尚未提交的外部 tra 所做的更改。
在這個(gè)內(nèi)部 tra 提交之后,甚至在外部 tra 提交之前,嵌套 tra 的更改將被提交并立即對(duì)其他 tra 可見。鎖更少,但由于提交更多的外部操作,redo-lock 中的記錄更多。
在性能方面,如果其他因素不重要,您可以在交易大小和交易數(shù)量之間找到收支平衡。如果嵌套的速度比 requires_new 快,那么這個(gè)問題沒有通用的答案。

TA貢獻(xiàn)1853條經(jīng)驗(yàn) 獲得超6個(gè)贊
如果您的內(nèi)部邏輯獨(dú)立于外部邏輯,則使用 Requires_new,如果不使用嵌套。
例如,您的外部方法可能正在處理包含大量記錄的作業(yè)并調(diào)用保持作業(yè)狀態(tài)(進(jìn)度、警告和驗(yàn)證錯(cuò)誤)的內(nèi)部方法。您希望內(nèi)部方法事務(wù)是獨(dú)立的,并且它的數(shù)據(jù)庫更改會(huì)立即保存,以便系統(tǒng)的其他部分可以顯示進(jìn)度。如果外部方法遇到異常,它的事務(wù)會(huì)回滾,但內(nèi)部方法的事務(wù)不會(huì)。
當(dāng)您需要將外部和內(nèi)部更改同時(shí)保留或同時(shí)回滾時(shí),您可能希望使用嵌套或依賴事務(wù)。例如,您需要?jiǎng)?chuàng)建一個(gè)新用戶(使用“外部”服務(wù))并保存他們的地址(使用“內(nèi)部”服務(wù))。如果您的要求是用戶必須有一個(gè)地址,那么如果保存用戶或地址失敗,您希望這兩個(gè)更改都回滾。
添加回答
舉報(bào)