這篇文章主要介紹“怎么理解Spring雙層事務(wù)”,在日常操作中,相信很多人在怎么理解Spring雙層事務(wù)問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”怎么理解Spring雙層事務(wù)”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

專(zhuān)注于為中小企業(yè)提供成都做網(wǎng)站、成都網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)宜豐免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了1000+企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
系統(tǒng) A 調(diào)用系統(tǒng) B 執(zhí)行數(shù)據(jù)同步,系統(tǒng) B 返回了錯(cuò)誤提示,系統(tǒng) A 需要將前邊保存的回滾掉,同時(shí)把錯(cuò)誤信息向上拋。
@Service("noteService")
public class NoteServiceImpl implements NoteService {
@Resource
private SearchService searchService;
@Transactional(rollbackFor = Throwable.class)
@Override
public CommonResponse<NoteEntity> save(NoteEntity note) {
// 一系列 DB 操作
try {
searchService.sync(note);
} catch (Exception e) {
e.printStackTrace();
}
return CommonResponse.success(entity);
}
}@Service("searchService")
public class SearchServiceImpl implements SearchService {
@Transactional(rollbackFor = Throwable.class)
@Override
public void sync(NoteEntity note) {
// 一系列 DB 操作
throw new RuntimeException("同步異常! [XXX]");
}
}@SpringBootTest
public class NoteTests {
@Resource
private NoteService noteService;
@Test
public void saveNote() {
NoteEntity entity = new NoteEntity();
entity.setTitle("念奴嬌赤壁懷古");
entity.setContent("大江東去,浪淘盡,千古風(fēng)流人物。故壘西邊,人道是:三國(guó)周郎赤壁。。。");
entity.setTags("蘇軾,宋代");
entity.setCategory("蘇軾詩(shī)詞");
try {
noteService.save(entity);
} catch (Exception e) {
e.printStackTrace();
// FIXME 我想在這里拿到的是 同步異常! [XXX]
// FIXME 但是這里拿到的是 Transaction silently rolled back because it has been marked as rollback-only
System.out.println(">>>>>>>>>> " + e.getMessage());
}
}
}代碼歷史久遠(yuǎn),為何這樣寫(xiě)已無(wú)從追溯。
納悶了一會(huì)兒,看到雙層事務(wù),就想起了 Spring事務(wù)傳播機(jī)制,前邊理解得比較膚淺。
沒(méi)有特殊的配置,自然是走默認(rèn)的事務(wù)傳播機(jī)制了,也就是 Propagation.REQUIRED。
國(guó)際慣例,列出事務(wù)傳播機(jī)制:
1、PROPAGATION_REQUIRED 當(dāng)前沒(méi)事務(wù),則創(chuàng)建事務(wù);存在事務(wù),就加入該事務(wù),這是最常用的設(shè)置。 2、PROPAGATION_SUPPORTS 當(dāng)前存在事務(wù),就加入事務(wù),當(dāng)前不存在事務(wù),就以非事務(wù)方式執(zhí)行。 3、PROPAGATION_MANDATORY 當(dāng)前存在事務(wù),就加入事務(wù);當(dāng)前不存在事務(wù),就拋出異常。 4、PROPAGATION_REQUIRES_NEW 無(wú)條件創(chuàng)建新事務(wù)。 5、PROPAGATION_NOT_SUPPORTED 以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),就將當(dāng)前事務(wù)掛起。 6、PROPAGATION_NEVER 以非事務(wù)方式運(yùn)行,如果存在事務(wù),就拋出異常。 7、PROPAGATION_NESTED 開(kāi)始執(zhí)行事務(wù)前,先保存一個(gè)savepoint,當(dāng)發(fā)生異常時(shí),就回滾到savepoint;沒(méi)有異常時(shí),跟著外部事務(wù)一起提交或回滾。
1、看了上邊的事務(wù)傳播機(jī)制,繼續(xù)細(xì)化問(wèn)題,內(nèi)外層共用一個(gè)事務(wù),內(nèi)層拋出異常,會(huì)導(dǎo)致整個(gè)事務(wù)失敗。
2、繼續(xù)分析,外層邏輯進(jìn)行了 try catch,就導(dǎo)致內(nèi)層的異常無(wú)法繼續(xù)向上拋出,外層事務(wù)會(huì)繼續(xù)提交。
3、事務(wù)提交時(shí),進(jìn)行事務(wù)狀態(tài)的判斷,就發(fā)現(xiàn)這個(gè)事務(wù)是失敗的,需要回滾,所以拋出了 Transaction silently rolled back because it has been marked as rollback-only 的異常。
銀彈自然是沒(méi)有的,根據(jù)業(yè)務(wù)場(chǎng)景選擇合適的方案。
1、當(dāng)前這種場(chǎng)景,直接把外層邏輯中的 try catch 去掉即可。異常直接向上拋,事務(wù)就不會(huì)繼續(xù)提交,調(diào)用方拿到的就是一手的異常;
2、如果內(nèi)層不是核心邏輯,記錄個(gè)日志啥的,可以把內(nèi)層事務(wù)配置為 @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRES_NEW), 無(wú)論如何,都創(chuàng)建新的事務(wù),外層事務(wù)不受內(nèi)層事務(wù)影響。但是有個(gè)問(wèn)題,外層事務(wù)失敗了,內(nèi)層事務(wù)還是把記錄入庫(kù)了,有可能產(chǎn)生臟數(shù)據(jù);
3、如果外層事務(wù)失敗了,內(nèi)層事務(wù)也不能提交,那就可以使用 @Transactional(rollbackFor = Throwable.class, propagation = Propagation.NESTED)。 注意:hibernate/jpa 不支持嵌套事務(wù) NESTED,可用 JdbcTemplate 代替。
到此,關(guān)于“怎么理解Spring雙層事務(wù)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
當(dāng)前標(biāo)題:怎么理解Spring雙層事務(wù)
分享路徑:http://chinadenli.net/article48/goipep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、網(wǎng)站改版、網(wǎng)站收錄、網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)