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

Spring的@Transactional嵌套解讀

 更新時間:2024年11月08日 15:18:03   作者:Lanje?Wang  
本文通過詳細測試,探究了Spring的@Transactional注解在事務嵌套和局部回滾場景下的行為表現(xiàn),文中通過多個測試案例,闡述了不同傳播行為(如REQUIRES_NEW)對事務嵌套處理的影響,以及rollbackFor屬性在異常管理中的作用和限制,通過實驗總結(jié)

事務嵌套局部回滾的問題,很是費解。

本文將做一個詳細的測試,加強對Spring的@Transactional 理解和使用

1、兩個單獨不干擾事務

	@RequestMapping("/test")
    public void test() {
        LoveFile test1 = new LoveFile();
        test1.setFileUuid(get32Uuid());
        test1.setFileName("test1");
        loveFileService.test1(test1);
        LoveFile test2 = new LoveFile();
        test2.setFileUuid(null);
        test2.setFileName("test2");
        loveFileService.test2(test2);
    }
    @Override
    @Transactional
    public void test1(LoveFile loveFile) {
        mapper.insertSelective(loveFile);

    }
    @Override
    @Transactional
    public void test2(LoveFile loveFile) {
        mapper.insertSelective(loveFile);
    }

由于我給第二個test2插入主鍵為空,報錯。因此庫里只有一條

總結(jié):兩個單獨事務互不干擾。錯了就是錯了,很好理解

2、普通嵌套事務

	@RequestMapping("/test")
    @Transactional
    public void test() {
        LoveFile test1 = new LoveFile();
        test1.setFileUuid(get32Uuid());
        test1.setFileName("test1");
        loveFileService.test1(test1);
        LoveFile test2 = new LoveFile();
        test2.setFileUuid(null);
        test2.setFileName("test2");
        loveFileService.test2(test2);
    }

子事務不變,刪除剛才的數(shù)據(jù)后,測試。

庫里空空。

總結(jié):加在外層的事務起了作用,在test2報錯時回滾了test1

3、嵌套事務、三個子事務中間一個加(propagation = Propagation.REQUIRES_NEW)

Propagation取值:

  • REQUIRED(默認值):在有transaction狀態(tài)下執(zhí)行;如當前沒有transaction,則創(chuàng)建新的transaction;
  • SUPPORTS:如當前有transaction,則在transaction狀態(tài)下執(zhí)行;如果當前沒有transaction,在無transaction狀態(tài)下執(zhí)行;
  • MANDATORY:必須在有transaction狀態(tài)下執(zhí)行,如果當前沒有transaction,則拋出異常IllegalTransactionStateException;
  • REQUIRES_NEW:創(chuàng)建新的transaction并執(zhí)行;如果當前已有transaction,則將當前transaction掛起;
  • NOT_SUPPORTED:在無transaction狀態(tài)下執(zhí)行;如果當前已有transaction,則將當前transaction掛起;
  • NEVER:在無transaction狀態(tài)下執(zhí)行;如果當前已有transaction,則拋出異常IllegalTransactionStateException。

本文重點研究 REQUIRES_NEW

@RequestMapping("/test")
    @Transactional
    public void test() {
        LoveFile test1 = new LoveFile();
        test1.setFileUuid(get32Uuid());
        test1.setFileName("test1");
        loveFileService.test1(test1);
        LoveFile test3 = new LoveFile();
        test3.setFileUuid(get32Uuid());
        test3.setFileName("test3");
        loveFileService.test3(test3);
        LoveFile test2 = new LoveFile();
        test2.setFileUuid(null);
        test2.setFileName("test2");
        loveFileService.test2(test2);
    }
@Override
    @Transactional
    public void test1(LoveFile loveFile) {
        mapper.insertSelective(loveFile);
    }
    @Override
    @Transactional
    public void test2(LoveFile loveFile) {
        mapper.insertSelective(loveFile);
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void test3(LoveFile loveFile) {
        mapper.insertSelective(loveFile);
    }

REQUIRES_NEW官方文檔解釋:

Create a new transaction, and suspend the current transaction if one exists.

意思是,創(chuàng)建一個新事務,如果當前存在事務,將這個事務掛起。

也就是說test3,是獨立于外層事務的單獨的事務,他已經(jīng)掛起的外層事務,他要把自己的問題處理完再去管別人。

因此結(jié)果是

總結(jié):不給子事務加(propagation = Propagation.REQUIRES_NEW),相當于加入了外層事務。加了則當做新的子事務。

test2報錯了,影響了test1 ,卻不能影響test3,已經(jīng)說明了此問題

4、嵌套事務、三個子事務中間一個加(propagation = Propagation.REQUIRES_NEW),偏偏出錯了

	@RequestMapping("/test")
    @Transactional
    public void test() {
        LoveFile test1 = new LoveFile();
        test1.setFileUuid(get32Uuid());
        test1.setFileName("test1");
        loveFileService.test1(test1);
        LoveFile test3 = new LoveFile();
        test3.setFileUuid(null);
        test3.setFileName("test3");
        loveFileService.test3(test3);
        LoveFile test2 = new LoveFile();
        test2.setFileUuid(get32Uuid());
        test2.setFileName("test2");
        loveFileService.test2(test2);
    }

我把test3主鍵為空,因此他會有SQLException。來研究下,他會不會影響整體。

總結(jié): 雖然他是開辟的新事物,但是出錯了,還是會牽連整體的

至此,(propagation = Propagation.REQUIRES_NEW) 已經(jīng)解釋清楚了。

我覺得子事務,不加這個東西的話不叫子事務。不加的話直接加入了外層事務。那還要個單單 @Transactional何用?

建議大家對子事務都加上這條件。

rollbackFor官方文檔解釋:

在@Transactional注解中如果不配置rollbackFor屬性,那么事物只會在遇到RuntimeException的時候才會回滾,加上rollbackFor=Exception.class,可以讓事物在遇到非運行時異常時也回滾

5、rollbackFor了一個異常,卻會報另外異常

@RequestMapping("/test")
    @Transactional
    public void test() {
        LoveFile test1 = new LoveFile();
        test1.setFileUuid(get32Uuid());
        test1.setFileName("test1");
        loveFileService.test1(test1);
        LoveFile test3 = new LoveFile();
        test3.setFileUuid(null);
        test3.setFileName("test3");
        loveFileService.test3(test3);
        LoveFile test2 = new LoveFile();
        test2.setFileUuid(get32Uuid());
        test2.setFileName("test2");
        loveFileService.test2(test2);
    }
 @Override
    @Transactional
    public void test1(LoveFile loveFile) {
        mapper.insertSelective(loveFile);
    }
    @Override
    @Transactional
    public void test2(LoveFile loveFile) {
        mapper.insertSelective(loveFile);
    }
    @Override
    @Transactional(rollbackFor=SQLException.class,propagation = Propagation.REQUIRES_NEW)
    public void test3(LoveFile loveFile) {
        int  a = 1/0;
       // mapper.insertSelective(loveFile);
    }

這個test3,一定會報 by zero,他會報錯,我來測試下,他會不會回滾,影響他人。

如此是影響了。

因為外層事務沒有聲明異常,他看到一個內(nèi)部報by zero 了,而自己是RuntimeException,包含在內(nèi)。因此自己回滾了。

test1 是直接加入整體的。沒加出數(shù)據(jù),就說明了此問題。

我其實是像測試,test3是否回滾,這個測試案例不合適。

@RequestMapping("/test")
    @Transactional
    public void test() {
        LoveFile test1 = new LoveFile();
        test1.setFileUuid(get32Uuid());
        test1.setFileName("test1");
        loveFileService.test1(test1);
        LoveFile test3 = new LoveFile();
        test3.setFileUuid(get32Uuid());
        test3.setFileName("test3");
        loveFileService.test3(test3);
        LoveFile test2 = new LoveFile();
        test2.setFileUuid(get32Uuid());
        test2.setFileName("test2");
        loveFileService.test2(test2);
    }
   @Override
    @Transactional
    public void test1(LoveFile loveFile) {
        mapper.insertSelective(loveFile);
    }
    @Override
    @Transactional
    public void test2(LoveFile loveFile) {
        mapper.insertSelective(loveFile);
    }
    @Override
    @Transactional(rollbackFor=SQLException.class,propagation = Propagation.REQUIRES_NEW)
    public void test3(LoveFile loveFile) {
        mapper.insertSelective(loveFile);
        int  a = 1/0;
    }

我給了test3 正常的主鍵,讓他添加成功,卻在后面 by zero .因為我認為他不會回滾,這次應該是test3加進去了,test1和test2被外層事務回滾。

但是結(jié)果是:

我又做了一些測試,發(fā)現(xiàn)rollbackFor=SQLException.class 這樣的聲明一個特定的異常沒有任何效果。

rollbackFor 用途不大,就是聲明rollbackFor=Exception.class 時比 RuntimeException 廣一些。

其他時用途不大。

如果想讓特定異常不回滾,還不如用 try catch。只要異常被catch住,不被方法知道,就不會出現(xiàn)error ,也就不會回滾。

總結(jié)

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

相關文章

  • Java 中的抽象介紹

    Java 中的抽象介紹

    這篇文章主要介紹了Java 中的抽象,數(shù)據(jù)抽象是一種僅向用戶顯示基本細節(jié)的屬性。不向用戶顯示瑣碎或非必需的單元,下面文章Java抽象詳細內(nèi)容,需要的朋友可以參考一下
    2021-12-12
  • SpringCloud Bus消息總線的實現(xiàn)

    SpringCloud Bus消息總線的實現(xiàn)

    消息總線是一種通信工具,可以在機器之間互相傳輸消息、文件等,這篇文章主要介紹了SpringCloud Bus消息總線的實現(xiàn),Spring cloud bus 通過輕量消息代理連接各個分布的節(jié)點,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Java中的序列化和反序列化使用及解讀

    Java中的序列化和反序列化使用及解讀

    文章總結(jié)了Java中序列化和反序列化的概念,包括序列化的用途、實現(xiàn)方式和注意事項,此外,還介紹了其他幾種常見的序列化框架,如JSON序列化、ProtocolBuffers和Kryo,并給出了最佳實踐和使用場景建議
    2026-02-02
  • 自定義log4j2中的Appender來獲取日志內(nèi)容的示例代碼

    自定義log4j2中的Appender來獲取日志內(nèi)容的示例代碼

    在 Log4j2 中,Appender 是負責將日志事件輸出到目標地點的組件,本文講述的是通過 log4j 中自定義的 Appender 來獲取需要打印的日志信息,文中有詳細的代碼示例供大家參考,需要的朋友可以參考下
    2024-02-02
  • spring-boot使用Admin監(jiān)控應用的方法

    spring-boot使用Admin監(jiān)控應用的方法

    本篇文章主要介紹了spring-boot使用Admin監(jiān)控應用的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • mybatis框架order by作為參數(shù)傳入時失效的解決

    mybatis框架order by作為參數(shù)傳入時失效的解決

    這篇文章主要介紹了mybatis框架order by作為參數(shù)傳入時失效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • JAVA獲取當前項目和文件所在路徑的實例代碼

    JAVA獲取當前項目和文件所在路徑的實例代碼

    這篇文章主要介紹了JAVA獲取當前項目和文件所在路徑的實例代碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • 解決mybatisplus插入報錯argument type mismatch的問題

    解決mybatisplus插入報錯argument type mismatch的問題

    這篇文章主要介紹了解決mybatisplus插入報錯argument type mismatch的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Java文件操作實例詳解

    Java文件操作實例詳解

    這篇文章主要為大家詳細介紹了Java文件操作實例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • java jni調(diào)用c函數(shù)實例分享(java調(diào)用c函數(shù))

    java jni調(diào)用c函數(shù)實例分享(java調(diào)用c函數(shù))

    Java代碼中調(diào)用C/C++代碼,當然是使用JNI,JNI是Java native interface的簡寫,可以譯作Java原生接口,下面看實例吧
    2013-12-12

最新評論

彰化市| 苏尼特左旗| 阳信县| 南平市| 贡觉县| 阿巴嘎旗| 吴川市| 宁晋县| 乐东| 武冈市| 辛集市| 乌恰县| 邳州市| 吉安市| 太康县| 新龙县| 炎陵县| 饶平县| 桐城市| 孝义市| 定陶县| 天门市| 博白县| 琼结县| 高台县| 景泰县| 招远市| 彭阳县| 黄陵县| 涡阳县| 铜鼓县| 开江县| 栖霞市| 无锡市| 辛集市| 睢宁县| 浠水县| 广宁县| 阿图什市| 盘山县| 梁河县|