最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
遇到Spring雙層事務(wù)不回滾怎么辦

今天就跟大家聊聊有關(guān)遇到Spring雙層事務(wù)不回滾怎么辦,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

成都創(chuàng)新互聯(lián)不只是一家網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司;我們對(duì)營(yíng)銷(xiāo)、技術(shù)、服務(wù)都有自己獨(dú)特見(jiàn)解,公司采取“創(chuàng)意+綜合+營(yíng)銷(xiāo)”一體化的方式為您提供更專(zhuān)業(yè)的服務(wù)!我們經(jīng)歷的每一步也許不一定是最完美的,但每一步都有值得深思的意義。我們珍視每一份信任,關(guān)注我們的成都做網(wǎng)站、成都網(wǎng)站建設(shè)質(zhì)量和服務(wù)品質(zhì),在得到用戶滿意的同時(shí),也能得到同行業(yè)的專(zhuān)業(yè)認(rèn)可,能夠?yàn)樾袠I(yè)創(chuàng)新發(fā)展助力。未來(lái)將繼續(xù)專(zhuān)注于技術(shù)創(chuàng)新,服務(wù)升級(jí),滿足企業(yè)一站式營(yíng)銷(xiāo)型網(wǎng)站建設(shè)需求,讓再小的成都品牌網(wǎng)站建設(shè)也能產(chǎn)生價(jià)值!

最近有粉絲在朋友圈問(wèn)我,面試遇到了Spring雙事務(wù)不會(huì)滾問(wèn)題,怎么破解。下面結(jié)合一個(gè)簡(jiǎ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 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 的異常。

怎么解決?

根據(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 代替。

最后,下面這位粉絲總結(jié)的事務(wù)不生效問(wèn)題,大家牢記。面試中能全說(shuō)出來(lái),Offer基本穩(wěn)了。

看完上述內(nèi)容,你們對(duì)遇到Spring雙層事務(wù)不回滾怎么辦有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。


文章標(biāo)題:遇到Spring雙層事務(wù)不回滾怎么辦
新聞來(lái)源:http://fisionsoft.com.cn/article/gicidd.html