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

spring中@Transactional?注解失效的原因及解決辦法

 更新時間:2024年06月05日 09:19:02   作者:睡個好覺  
面試中經(jīng)常會被問到事務失效的場景有哪些,本文主要介紹了spring中@Transactional?注解失效的原因及解決辦法,具有一定的參考價值,感興趣的可以了解一下

前言

面試中經(jīng)常會被問到事務失效的場景有哪些,其實在開發(fā)中,若是不了解事務失效的場景,當你覺得加了事務,就會回滾,就大錯特錯了,今天就來了解一下吧。

一、@Transactional 屬性介紹

1.事務的傳播行為:propagation

這就是我們常說的事務的七種傳播行為,默認值:Propagation.REQUIRED

屬性解釋
Propagation.REQUIRED如果當前存在事務,則加入該事務,如果當前不存在事務,則創(chuàng)建一個新的事務。
Propagation.SUPPORTS如果當前存在事務,則加入該事務;如果當前不存在事務,則以非事務的方式繼續(xù)運行。
Propagation.MANDATORY如果當前存在事務,則加入該事務;如果當前不存在事務,則拋出異常。
Propagation.REQUIRES_NEW重新創(chuàng)建一個新的事務,如果當前存在事務,暫停當前的事務。
Propagation.NOT_SUPPORTED以非事務的方式運行,如果當前存在事務,暫停當前的事務。
Propagation.NEVER以非事務的方式運行,如果當前存在事務,則拋出異常。
Propagation.NESTED嵌套事務。

2.事務的隔離級別:isolation

這就是我們常說的事務的隔離級別,默認值:Isolation.DEFAULT

屬性解釋
Isolation.DEFAULT使用底層數(shù)據(jù)庫默認的隔離級別
Isolation.READ_UNCOMMITTED讀未提交
Isolation.READ_COMMITTED讀已提交
Isolation.REPEATABLE_READ可重復讀
Isolation.SERIALIZABLE串行化

3.事務的超時時間:timeout

  • timeout :事務的超時時間,默認值為 -1。如果超過該時間限制但事務還沒有完成,則自動回滾事務。

4.事務的回滾類型:rollbackFor

  • rollbackFor :用于指定能夠觸發(fā)事務回滾的異常類型,可以指定多個異常類型。

二、@Transactional 失效場景

1.同一個類中方法調(diào)用,注解失效

場景重現(xiàn):當調(diào)用 saveCabinet 方法時,save 方法中出異常不會回滾,如下代碼

@Service
public class CabinetServiceImpl implements CabinetService {
    @Autowired
    private CabinetMapper cabinetMapper;
    @Override
    public void saveCabinet(Cabinet cabinet) {
        save(cabinet);
    }
    @Transactional(rollbackFor = Exception.class)
    public void save(Cabinet cabinet) {
        cabinetMapper.insert(cabinet);
        int i = 1/0;	// 模擬出錯
    }
}

原因分析:spring 中采用動態(tài)代理來實現(xiàn)事務,當同一個類調(diào)用 save 時,不是代理類在調(diào)用,所以掃描不到事務注解

解決方案1:將 save 方法提到另一個類中,saveCabinet 調(diào)用另一個類的 save 方法(推薦使用)

// 當前類
@Service
public class CabinetServiceImpl implements CabinetService {
    @Autowired
    private MethodTest methodTest;
    @Override
    public void saveCabinet(Cabinet cabinet) {
        methodTest.save(cabinet);
    }
}
// 另一個類
@Service
public class MethodTest {
    @Autowired
    private CabinetMapper cabinetMapper;
    
    @Transactional(rollbackFor = Exception.class)
    public void save(Cabinet cabinet) {
        cabinetMapper.insert(cabinet);
        int i = 1/0; 	// 模擬出錯
    }
}

解決方案2:在 CabinetServiceImpl 中自己注入自己,用自己的代理類調(diào)用 save 方法,即 cabinetServiceImpl.save()

@Service
public class CabinetServiceImpl implements CabinetService {
    @Autowired
    private CabinetMapper cabinetMapper;
    
    @Autowired
    private CabinetServiceImpl cabinetServiceImpl;
    
    @Override
    public void saveCabinet(Cabinet cabinet) {
        cabinetServiceImpl.save(cabinet);
    }
    
    @Transactional(rollbackFor = Exception.class)
    public void save(Cabinet cabinet) {
        cabinetMapper.insert(cabinet);
        int i = 1/0;	// 模擬出錯
    }
}

2.異常被 catch “吃了”,注解失效

場景重現(xiàn):當調(diào)用 saveCabinet 方法時,方法體被 try-catch 了,不會回滾,如下代碼

@Service
public class CabinetServiceImpl implements CabinetService {
    @Autowired
    private CabinetMapper cabinetMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveCabinet(Cabinet cabinet) {
        try {
            cabinetMapper.insert(cabinet);
            int i = 1/0;	// 模擬出錯
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

原因分析:異常直接捕獲沒有向上拋出,而是自己處理了,注解捕獲不到異常,所以失效

解決方案:將 catch 到的異常向上拋出 throw new Exception(e);,異常交給注解處理

@Service
public class CabinetServiceImpl implements CabinetService {
    @Autowired
    private CabinetMapper cabinetMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveCabinet(Cabinet cabinet) throws Exception {
        try {
            cabinetMapper.insert(cabinet);
            int i = 1/0;	// 模擬出錯
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e);
        }
    }
}

3.@Transactional 應用在非 public 修飾的方法上

  • 場景重現(xiàn):當調(diào)用的方法不是 public 修飾時,不會回滾,事務失效
  • 原因分析:在 spring aop 代理時,事務攔截器會在目標方法的執(zhí)行前后進行攔截,其中的方法會去獲取 Transactional 注解的一些信息,而其中的方法會去檢查目標方法是否被 public 修飾,不是的話獲取不到注解信息
  • 解決方案:將調(diào)用的方法訪問修飾符改為 public

4.@Transactional 注解屬性 rollbackFor 設置錯誤

場景重現(xiàn):當注解沒有指定 rollbackFor 屬性時,如下若拋出 FileNotFoundException 異常則不會回滾

@Service
public class CabinetServiceImpl implements CabinetService {
    @Autowired
    private CabinetMapper cabinetMapper;
    
    @Override
    @Transactional
    public void saveCabinet(Cabinet cabinet) throws IOException {
        cabinetMapper.insert(cabinet);
        // 模擬出錯
        throw new FileNotFoundException();
    }
}

原因分析:spring 默認拋出未檢查異常,繼承 RuntimeException 或者 Error 才會回滾,其他異常如 FileNotFoundException 則不會回滾

解決方案:指定 rollbackFor 屬性,一般指定 @Transactional(rollbackFor = Exception.class) 即可,也可以指定自定義異常

@Service
public class CabinetServiceImpl implements CabinetService {
    @Autowired
    private CabinetMapper cabinetMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveCabinet(Cabinet cabinet) throws IOException {
        cabinetMapper.insert(cabinet);
        // 模擬出錯
        throw new FileNotFoundException();
    }
}

5.@Transactional 注解屬性 propagation 設置錯誤

  • 使用了不支持事務的傳播屬性

6.數(shù)據(jù)庫引擎不支持事務

  • 數(shù)據(jù)庫不支持事務

總結(jié)

到此這篇關(guān)于spring中@Transactional 注解失效的原因及解決辦法的文章就介紹到這了,更多相關(guān)spring @Transactional 失效內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java遞歸遍歷文件目錄代碼實例

    Java遞歸遍歷文件目錄代碼實例

    這篇文章主要介紹了Java遞歸遍歷文件目錄代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • 淺析Java中的虛擬線程

    淺析Java中的虛擬線程

    在本篇文章中,小編將帶大家深入了解Java虛擬線程的原理、如何使用、使用的注意事項以及其他相似技術(shù)的差別,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-10-10
  • Netty分布式高性能工具類recycler的使用及創(chuàng)建

    Netty分布式高性能工具類recycler的使用及創(chuàng)建

    這篇文章主要為大家介紹了Netty分布式高性能工具類recycler的使用和創(chuàng)建,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • 通過Java視角簡單談談局部性原理

    通過Java視角簡單談談局部性原理

    程序的局部性原理是指程序在執(zhí)行時呈現(xiàn)出局部性規(guī)律,即在一段時間內(nèi),整個程序的執(zhí)行僅限于程序中的某一部分,這篇文章主要給大家介紹了關(guān)于通過Java視角簡單談談局部性原理的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • SpringBoot自動配置類加載順序與優(yōu)先級

    SpringBoot自動配置類加載順序與優(yōu)先級

    本文詳細介紹了Spring?Boot自動配置類的加載順序與優(yōu)先級,首先說明了加載順序的重要性及典型問題,然后拆解了Spring?Boot的默認優(yōu)先級體系,需要的朋友可以參考下
    2026-04-04
  • Java語言實現(xiàn)非遞歸實現(xiàn)樹的前中后序遍歷總結(jié)

    Java語言實現(xiàn)非遞歸實現(xiàn)樹的前中后序遍歷總結(jié)

    今天小編就為大家分享一篇關(guān)于Java語言實現(xiàn)非遞歸實現(xiàn)樹的前中后序遍歷總結(jié),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Spring深入分析容器接口作用

    Spring深入分析容器接口作用

    Spring內(nèi)部提供了很多表示Spring容器的接口和對象,我們今天來看看幾個比較常見的容器接口和具體的實現(xiàn)類,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • 數(shù)組在java中的擴容的實例方法

    數(shù)組在java中的擴容的實例方法

    在本篇文章里小編給大家分享的是一篇關(guān)于數(shù)組在java中的擴容的實例方法內(nèi)容,有興趣的朋友們可以學習下。
    2021-01-01
  • Java異常堆棧打印次數(shù)限制機制用法詳解

    Java異常堆棧打印次數(shù)限制機制用法詳解

    在Java開發(fā)中,異常處理是保證程序健壯性的重要手段,但當同一個異常被頻繁拋出時,日志可能會被大量重復的堆棧信息淹沒,影響問題排查效率,所以本文給大家介紹了Java異常堆棧打印次數(shù)限制機制的用法,需要的朋友可以參考下
    2025-04-04
  • SpringBoot事件監(jiān)聽器@EventListener的實現(xiàn)

    SpringBoot事件監(jiān)聽器@EventListener的實現(xiàn)

    @EventListener注解用于處理應用程序事件,提供了一種方便的方式來監(jiān)聽和響應各種事件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-11-11

最新評論

禹州市| 昭觉县| 兴文县| 临沧市| 桂阳县| 逊克县| 台南市| 鄂托克前旗| 龙海市| 保靖县| 日喀则市| 茂名市| 丽江市| 屏山县| 龙川县| 隆回县| 枣阳市| 屏东县| 新疆| 靖安县| 鹰潭市| 铁力市| 乌兰浩特市| 德兴市| 桐城市| 陈巴尔虎旗| 二连浩特市| 于田县| 涪陵区| 上虞市| 澳门| 诏安县| 崇文区| 黑水县| 兴业县| 溧阳市| 洛南县| 浦城县| 澄城县| 黑山县| 和平县|