最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

我總結(jié)的幾種@Transactional失效原因說明

 更新時間:2022年11月15日 15:53:49   作者:滕青山Y(jié)YDS  
這篇文章主要是我總結(jié)的幾種@Transactional失效原因說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

總結(jié)幾種@Transactional失效原因

非public方法

spring事務(wù)是通過動態(tài)代理的方法來實現(xiàn)的,有兩種實現(xiàn)動態(tài)代理的方式,jdk動態(tài)代理方式是將目標(biāo)對象放入代理對象內(nèi)部,通過代理對象來訪問目標(biāo)對象;cglib字節(jié)碼生成是通過生成目標(biāo)對象的子類,通過重寫的方式來完成對父類的增強(qiáng)。

但是它倆實際上可以為非public方法生成代理對象,只不過spring在調(diào)用動態(tài)代理之前,會過濾掉非public方法。如果修改spring的源碼就可以為非public方法生成代理對象了。

自調(diào)用問題

若同一類中的沒有@Transactional注解的方法內(nèi)部調(diào)用有@Transactional注解的方法,那么該事務(wù)會被忽略。

原因是Spring事務(wù)是通過Spring AOP完成的,如果從外部直接訪問使用@Transactional注解的方法,那么spring實際上會調(diào)用代理對象上的方法,在代理對象中完成事務(wù)的邏輯;

但是如果從目標(biāo)對象內(nèi)部調(diào)用了使用@Transactional注解的方法,比如在method1方法中調(diào)用了method2方法,method1沒有加@Transactional 注解,就算method2加了@Transactional 注解也沒用。因為這時會直接調(diào)用目標(biāo)對象中的method1方法,進(jìn)而再調(diào)用目標(biāo)對象的method2方法,并沒有走代理對象導(dǎo)致代理失效。

異常相關(guān)問題

內(nèi)部捕捉了異常,沒有拋出新的異常,導(dǎo)致事務(wù)操作不會進(jìn)行回滾:

原因是spring事務(wù)源碼中是通過有沒有出現(xiàn)異常來判斷是否回滾的。

拋出非運(yùn)行時異常

所以最好給@Transactional添加上rollbackFor=Exception.class

傳播機(jī)制配置錯誤

錯誤地使用傳播機(jī)制也會導(dǎo)致事務(wù)失效。如果使用了NOT_SUPPORTED和NEVER傳播機(jī)制,那么事務(wù)機(jī)會失效,如果使用了SUPPORTS傳播機(jī)制并且當(dāng)前不存在事務(wù)那么事務(wù)也會失效。

  • TransactionDefinition.PROPAGATION_SUPPORTS: 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則以非事務(wù)的方式繼續(xù)運(yùn)行。
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。
  • TransactionDefinition.PROPAGATION_NEVER: 以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異常。

@Transactional事務(wù)失效場景類內(nèi)部調(diào)用實測

環(huán)境springboot2.7,mysql5.7

demo1

@Component
@Order(6)
@Slf4j
public class TestRunner implements ApplicationRunner {
 
    @Autowired
    TestService testService;
 
    @Override
    public void run(ApplicationArguments args) throws Exception {
        testService.insertAndUpdate();
    }
}
@Service("testService")
public class TestServiceImpl extends ServiceImpl<TestMapper, Test> implements TestService {
 
    @Override
    public boolean updateByIdOne() {
        LambdaUpdateWrapper<Test> lambdaUpdateWrapper = new UpdateWrapper<Test>().lambda();
        lambdaUpdateWrapper.eq(Test::getId,1);
        lambdaUpdateWrapper.set(Test::getName,"test");
 
        return this.update(lambdaUpdateWrapper);
    }
 
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean insertAndUpdate() {
        boolean b = this.updateByIdOne();
 
 
        Test test = new Test();
        test.setName("2222");
 
 
        boolean save = this.save(test);
        if(b){
            throw new RuntimeException("ts");
        }
        return save;
    }
}

以上代碼先跑一遍,看看拋出異常情況,能不能回滾

看庫  毫無變化

看主鍵遞增量其實是插入過了,我覺得事務(wù)還是生效了

demo2

@Service("testService")
public class TestServiceImpl extends ServiceImpl<TestMapper, Test> implements TestService {
 
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean updateByIdOne() {
        LambdaUpdateWrapper<Test> lambdaUpdateWrapper = new UpdateWrapper<Test>().lambda();
        lambdaUpdateWrapper.eq(Test::getId,1);
        lambdaUpdateWrapper.set(Test::getName,"test");
        boolean update = this.update(lambdaUpdateWrapper);
 
        if(update){
            throw new RuntimeException("updateByIdOne");
        }
 
        LambdaUpdateWrapper<Test> lambdaUpdateWrapper2 = new UpdateWrapper<Test>().lambda();
        lambdaUpdateWrapper2.eq(Test::getId,2);
        lambdaUpdateWrapper2.set(Test::getName,"test");
        boolean update1 = this.update(lambdaUpdateWrapper2);
 
        return update;
    }
 
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean insertAndUpdate() {
 
        Test test = new Test();
        test.setName("2222");
        boolean save = this.save(test);
 
        boolean b = this.updateByIdOne();
 
        return save;
    }
}

執(zhí)行結(jié)果

子父方法都有事務(wù)注解,事務(wù)生效

demo3

@Service("testService")
public class TestServiceImpl extends ServiceImpl<TestMapper, Test> implements TestService {
 
    @Override
    public boolean updateByIdOne() {
        LambdaUpdateWrapper<Test> lambdaUpdateWrapper = new UpdateWrapper<Test>().lambda();
        lambdaUpdateWrapper.eq(Test::getId,1);
        lambdaUpdateWrapper.set(Test::getName,"test");
        boolean update = this.update(lambdaUpdateWrapper);
 
        if(update){
            throw new RuntimeException("updateByIdOne");
        }
 
        return update;
    }
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean insertAndUpdate() {
 
        Test test = new Test();
        test.setName("2222");
        boolean save = this.save(test);
 
 
        boolean b = this.updateByIdOne();
        return b;
    }
}

insertAndUpdate插入成功后又回滾,update 更新成功也回滾,事務(wù)生效

demo4

@Service("testService")
public class TestServiceImpl extends ServiceImpl<TestMapper, Test> implements TestService {
 
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean updateByIdOne() {
        LambdaUpdateWrapper<Test> lambdaUpdateWrapper = new UpdateWrapper<Test>().lambda();
        lambdaUpdateWrapper.eq(Test::getId,1);
        lambdaUpdateWrapper.set(Test::getName,"test");
        boolean update = this.update(lambdaUpdateWrapper);
 
        if(update){
            throw new RuntimeException("updateByIdOne");
        }
 
        LambdaUpdateWrapper<Test> lambdaUpdateWrapper2 = new UpdateWrapper<Test>().lambda();
        lambdaUpdateWrapper2.eq(Test::getId,2);
        lambdaUpdateWrapper2.set(Test::getName,"test");
        boolean update1 = this.update(lambdaUpdateWrapper2);
 
        return update;
    }
 
    @Override
    public boolean insertAndUpdate() {
        boolean b = this.updateByIdOne();
 
        return b;
    }
}

以上代碼一跑,結(jié)果就很清楚了。

1、在同類中調(diào)用,二個方法都有加上事務(wù)注解,生效

2、同類中,子方法有事務(wù)注解,父類方法無事務(wù)注解,在controller層調(diào)用父類方法,子方法事務(wù)不生效

3、同類中,子方法無事務(wù)注解,父類方法有事務(wù)注解,在controller層調(diào)用父類方法,之方法事務(wù)生效

這些僅為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java實現(xiàn)簡單的貪吃蛇小游戲

    Java實現(xiàn)簡單的貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)簡單的貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • SpringBoot實現(xiàn)WebSocket服務(wù)并讓客戶端實時接收

    SpringBoot實現(xiàn)WebSocket服務(wù)并讓客戶端實時接收

    使用SpringBoot和WebSocket可創(chuàng)建實時消息推送服務(wù),首先添加WebSocket依賴至pom.xml,配置WebSocket端點和邏輯處理器,通過WebSocketHandler處理消息,使用AnnouncementController模擬消息推送,支持HTML和微信小程序客戶端接收消息,感興趣的可以了解一下
    2024-10-10
  • Java預(yù)防SQL注入的具體實踐方法

    Java預(yù)防SQL注入的具體實踐方法

    在?Java?中預(yù)防?SQL?注入的核心是?避免直接拼接?SQL?語句,并通過參數(shù)化查詢、ORM?框架和嚴(yán)格的輸入驗證來實現(xiàn)安全防護(hù),以下是具體實踐方法,感興趣的小伙伴跟著小編一起來看看吧
    2025-01-01
  • java實現(xiàn)學(xué)生管理系統(tǒng)(面向?qū)ο?

    java實現(xiàn)學(xué)生管理系統(tǒng)(面向?qū)ο?

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)學(xué)生管理系統(tǒng)(面向?qū)ο螅?,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • Java實現(xiàn)Excel百萬級數(shù)據(jù)導(dǎo)入功能的示例代碼

    Java實現(xiàn)Excel百萬級數(shù)據(jù)導(dǎo)入功能的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Java如何實現(xiàn)Excel百萬級數(shù)據(jù)導(dǎo)入功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,有需要的小伙伴可以參考下
    2024-04-04
  • JavaSE、JavaEE和JavaWeb三大工程目錄詳解

    JavaSE、JavaEE和JavaWeb三大工程目錄詳解

    這篇文章主要給大家介紹了關(guān)于JavaSE、JavaEE和JavaWeb三大工程目錄的相關(guān)資料,很多對java不是很了解的同學(xué)在看到課程?綱的時候發(fā)現(xiàn)??出現(xiàn)了JavaSE、JavaEE、JavaME、JavaWEB這些詞,搞得?頭霧?,需要的朋友可以參考下
    2023-07-07
  • Java多線程編程中線程鎖與讀寫鎖的使用示例

    Java多線程編程中線程鎖與讀寫鎖的使用示例

    這篇文章主要介紹了Java多線程編程中線程鎖與讀寫鎖的使用示例,鎖是控制程序多線程并發(fā)的重要手段,需要的朋友可以參考下
    2016-04-04
  • springcloud-gateway集成knife4j的示例詳解

    springcloud-gateway集成knife4j的示例詳解

    這篇文章主要介紹了springcloud-gateway集成knife4j的示例詳解,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • java中關(guān)于轉(zhuǎn)義字符的一個bug

    java中關(guān)于轉(zhuǎn)義字符的一個bug

    本文主要介紹了java中關(guān)于轉(zhuǎn)義字符的一個bug。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • SpringBoot深入淺出分析初始化器

    SpringBoot深入淺出分析初始化器

    這篇文章主要介紹了SpringBoot初始化器的分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07

最新評論

濮阳市| 泰州市| 武平县| 津南区| 衡山县| 东源县| 大同县| 正镶白旗| 龙里县| 龙井市| 宁津县| 东莞市| 来宾市| 华蓥市| 扶沟县| 上高县| 新安县| 长乐市| 鄢陵县| 泰州市| 察哈| 明星| 南充市| 平塘县| 德州市| 油尖旺区| 武山县| 房产| 罗甸县| 万山特区| 梁山县| 鄂托克旗| 阳高县| 扶沟县| 定州市| 封开县| 长春市| 阆中市| 山阳县| 资中县| 安国市|