欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring事務(wù)傳播中嵌套調(diào)用實(shí)現(xiàn)方法詳細(xì)介紹

 更新時(shí)間:2022年11月08日 17:06:35   作者:宏遠(yuǎn)十一冠王  
Spring事務(wù)的本質(zhì)就是對(duì)數(shù)據(jù)庫(kù)事務(wù)的支持,沒有數(shù)據(jù)庫(kù)事務(wù),Spring是無法提供事務(wù)功能的。Spring只提供統(tǒng)一的事務(wù)管理接口,具體實(shí)現(xiàn)都是由數(shù)據(jù)庫(kù)自己實(shí)現(xiàn)的,Spring會(huì)在事務(wù)開始時(shí),根據(jù)當(dāng)前設(shè)置的隔離級(jí)別,調(diào)整數(shù)據(jù)庫(kù)的隔離級(jí)別,由此保持一致

前言

最近在使用Spring框架時(shí)遇到了一些問題,主要是Spring的事務(wù)傳播問題,一個(gè)不帶事務(wù)的方法調(diào)用帶事務(wù)的方法,有時(shí)候會(huì)出現(xiàn)不回滾的情況,所以寫了這篇文章來記錄一下。

7種傳播方式

我們先來看Spring事務(wù)的7中傳播方式以及對(duì)應(yīng)的描述

屬性名稱描述
PROPAGATION__REQUIREDREQUIRED表示的是當(dāng)前這個(gè)方法必須運(yùn)行在一個(gè)事務(wù)環(huán)境中,如果當(dāng)前方法已經(jīng)處于事務(wù)環(huán)境中,就可以直接使用該方法,否則開啟一個(gè)新的事務(wù)
PROPAGATION_SUPPORTSSUPPORTS如果當(dāng)前方法處于事務(wù)環(huán)境中,就使用當(dāng)前事務(wù),否則不使用事務(wù)
PROPAGATION_MANDATORYMANDATORY表示當(dāng)前方法一定要處于事務(wù)環(huán)境中,否則就拋出異常
PROPAGATION_REQUIRES_NEWREQUIRES_NEW當(dāng)前方法需要運(yùn)行在新的事務(wù)中。如果當(dāng)前方法已在事務(wù)環(huán)境中,先暫停當(dāng)前事務(wù),在啟動(dòng)新的事務(wù)方法后才執(zhí)行該方法,如果當(dāng)前方法不在事務(wù)環(huán)境中,就啟動(dòng)一個(gè)新的事務(wù)后啟動(dòng)執(zhí)行該方法。
PROPAGATION_NOT_SUPPORTEDNOT_SUPPORTED不支持當(dāng)前的事務(wù),總是以非事務(wù)狀態(tài)執(zhí)行。如果這個(gè)方法是事務(wù)方法,就先掛起這個(gè)事務(wù)方法,再執(zhí)行這個(gè)方法
PROPAGATION_NEVERNEVER不支持當(dāng)前事務(wù),如果是事務(wù)方法,則拋出異常
PROPAGATION__NESTEDNESTED如果當(dāng)前執(zhí)行的方法處于事務(wù)環(huán)境中,依舊會(huì)啟動(dòng)一個(gè)事務(wù),嵌套的事務(wù)也可以獨(dú)立于當(dāng)前事務(wù)獨(dú)立回滾和提交,如果當(dāng)前執(zhí)行的方法不在事務(wù)環(huán)境中,也會(huì)啟動(dòng)一個(gè)新事務(wù)。

注解式事務(wù)

在Spring中,我們常用@Transactional來標(biāo)注一個(gè)事務(wù)方法,如果有點(diǎn)進(jìn)去這個(gè)注解的源碼都可以看到Spring對(duì)于添加這個(gè)注解的方法,都會(huì)默認(rèn)將這個(gè)方法的事務(wù)的傳播等級(jí)設(shè)置為REQUIRED,也就是是當(dāng)前方法必須處于一個(gè)事務(wù)方法中,或者使用調(diào)用這個(gè)方法的事務(wù)行為。

下面我們來分析下這個(gè)注解在什么情況下會(huì)失效,并且需要怎么樣來去避免這種情況的發(fā)生。

事務(wù)的方法之間的調(diào)用

下面這個(gè)例子模仿的是一個(gè)帶事務(wù)的方法調(diào)用另外一個(gè)事務(wù)方法,在下面的這個(gè)方法報(bào)錯(cuò),查看當(dāng)前事務(wù)有沒有進(jìn)行回滾

@Override
    @Transactional(rollbackFor = Exception.class)
    public void saveWithDish(SetmealDto setmealDto){
        this.save(setmealDto);
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
    }
    @Transactional(rollbackFor = Exception.class)
    public void saveBa(List<SetmealDish> setmealDishes, SetmealDto setmealDto) throws Exception{
        setmealDishes = setmealDishes.stream().peek((item) -> item.setSetmealId(setmealDto.getId())).collect(Collectors.toList());
        setmealDishService.saveBatch(setmealDishes);
        int j = 2/0;
    }

根據(jù)事務(wù)的傳播等級(jí)來看,這種情況是肯定可以回滾的,但是如果是同一類中,像下面這種情況,同一個(gè)類中一個(gè)不帶事務(wù)的方法調(diào)用另外一個(gè)帶事務(wù)的方法,這種情況下它的事務(wù)會(huì)不會(huì)回滾呢?理論上我們覺得是會(huì)的,但是在測(cè)試的時(shí)候呢,我們發(fā)現(xiàn)這個(gè)事務(wù)并沒有進(jìn)行回滾,也就是說,這個(gè)事務(wù)注解@Transantional沒有生效

@Override
    public void saveWithDish(SetmealDto setmealDto) throws Exception{
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        saveBa(setmealDishes, setmealDto);
    }
    @Transactional(rollbackFor = Exception.class)
    public void saveBa(List<SetmealDish> setmealDishes, SetmealDto setmealDto) throws Exception{
        this.save(setmealDto);
        setmealDishes = setmealDishes.stream().peek((item) -> item.setSetmealId(setmealDto.getId())).collect(Collectors.toList());
        setmealDishService.saveBatch(setmealDishes);
        int j = 2/0;
    }

雖然這里我們報(bào)錯(cuò)了,但是數(shù)據(jù)庫(kù)中還是新增了一條剛剛我們添加的一條數(shù)據(jù),這樣可以說明,這是沒有添加事務(wù)的,也驗(yàn)證了上面我們的方法。

下面我們來看情況上,當(dāng)不同類之間類方法的調(diào)用,如果一個(gè)事務(wù)方法調(diào)用一個(gè)非事務(wù)方法,這樣非事務(wù)方法當(dāng)然可以獲取到當(dāng)前這個(gè)事務(wù)的,不會(huì)開啟一個(gè)新的事務(wù)。但是當(dāng)一個(gè)非事務(wù)方法調(diào)用一個(gè)不同類的事務(wù)方法時(shí),這樣會(huì)不會(huì)回滾呢,答案是會(huì)的,這邊我已經(jīng)進(jìn)行驗(yàn)證過了。

注意事項(xiàng)

我們需要記住Spring的默認(rèn)事務(wù)傳播等級(jí)是Required,在Spring掃描Bean時(shí),會(huì)掃描這個(gè)方法是否帶有@Transactional注解,如果是包含的話,Spring會(huì)動(dòng)態(tài)生成一個(gè)代理類(proxy),當(dāng)這個(gè)方法被調(diào)用時(shí),是由代理類來進(jìn)行調(diào)用的,而在初始化時(shí),同一個(gè)類下面,這個(gè)方法如果是沒有帶@Transactional注解調(diào)用一個(gè)@Transactional的方法的話,這個(gè)方法的調(diào)用是沒有經(jīng)過代理類的,就不會(huì)啟動(dòng)transactional,也就是在同一個(gè)類出現(xiàn)無效的現(xiàn)象出現(xiàn)

所以,解決的話,我們可以將這兩個(gè)方法分開到兩個(gè)不同的類中,所以我們可以知道在一個(gè)service類中,如果一個(gè)非事務(wù)方法調(diào)用一個(gè)帶事務(wù)的方法和事務(wù)方法之間的相互調(diào)用都不會(huì)開啟新的事務(wù)。

到此這篇關(guān)于Spring事務(wù)傳播中嵌套調(diào)用實(shí)現(xiàn)方法詳細(xì)介紹的文章就介紹到這了,更多相關(guān)Spring嵌套調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談java對(duì)象之間相互轉(zhuǎn)化的多種方式

    淺談java對(duì)象之間相互轉(zhuǎn)化的多種方式

    這篇文章主要介紹了淺談java對(duì)象之間相互轉(zhuǎn)化的多種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Java jwt使用公鑰字符串驗(yàn)證解析token鎖方法詳解

    Java jwt使用公鑰字符串驗(yàn)證解析token鎖方法詳解

    關(guān)于java獲取Token驗(yàn)證的問題相信很多人都遇見過,尤其是對(duì)剛接觸微信開發(fā)的人來說確實(shí)有點(diǎn)棘手,下面這篇文章主要給大家介紹了關(guān)于Java中token驗(yàn)證解析的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • SpringApplicationRunListener監(jiān)聽器源碼詳解

    SpringApplicationRunListener監(jiān)聽器源碼詳解

    這篇文章主要介紹了SpringApplicationRunListener監(jiān)聽器源碼詳解,springboot提供了兩個(gè)類SpringApplicationRunListeners、SpringApplicationRunListener(EventPublishingRunListener),spring框架還提供了一個(gè)ApplicationListener接口,需要的朋友可以參考下
    2023-11-11
  • Java自動(dòng)生成編號(hào)的方法步驟

    Java自動(dòng)生成編號(hào)的方法步驟

    在新增數(shù)據(jù)時(shí),往往需要自動(dòng)生成編號(hào),本文主要介紹了Java自動(dòng)生成編號(hào)的方法步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • MyBatis批量插入數(shù)據(jù)過程解析

    MyBatis批量插入數(shù)據(jù)過程解析

    這篇文章主要介紹了MyBatis批量插入數(shù)據(jù)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • java線程池使用及原理面試題

    java線程池使用及原理面試題

    很多面試官喜歡把線程池作為問題的起點(diǎn),然后延伸到其它內(nèi)容,由于我們專欄已經(jīng)說過隊(duì)列、線程、鎖面試題了,所以本章面試題還是以線程池為主
    2022-03-03
  • Mybatis實(shí)現(xiàn)一對(duì)一、一對(duì)多關(guān)聯(lián)查詢的方法(示例詳解)

    Mybatis實(shí)現(xiàn)一對(duì)一、一對(duì)多關(guān)聯(lián)查詢的方法(示例詳解)

    這篇文章主要介紹了Mybatis實(shí)現(xiàn)一對(duì)一、一對(duì)多關(guān)聯(lián)查詢的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • JavaSE實(shí)現(xiàn)圖書管理系統(tǒng)的示例代碼

    JavaSE實(shí)現(xiàn)圖書管理系統(tǒng)的示例代碼

    這篇博客是在學(xué)習(xí)了一部分Java基礎(chǔ)語法之后的練習(xí)項(xiàng)目,通過這個(gè)小項(xiàng)目的練習(xí),對(duì)Java中的類和對(duì)象,抽象類和接口等進(jìn)行熟悉理解??旄S小編一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Java跨域問題的幾種后端解決方式舉例詳解

    Java跨域問題的幾種后端解決方式舉例詳解

    跨域,是指瀏覽器不能執(zhí)行其他網(wǎng)站的腳本,它是由瀏覽器的同源策略造成的,是瀏覽器對(duì)JavaScript實(shí)施的安全限制,這篇文章主要給大家介紹了關(guān)于Java跨域問題的幾種后端解決方式的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • 對(duì)Java ArrayList的自動(dòng)擴(kuò)容機(jī)制示例講解

    對(duì)Java ArrayList的自動(dòng)擴(kuò)容機(jī)制示例講解

    今天小編就為大家分享一篇對(duì)Java ArrayList的自動(dòng)擴(kuò)容機(jī)制示例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10

最新評(píng)論