亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前言

面試中經(jīng)常會(huì)被問(wèn)到事務(wù)失效的場(chǎng)景有哪些,其實(shí)在開(kāi)發(fā)中,若是不了解事務(wù)失效的場(chǎng)景,當(dāng)你覺(jué)得加了事務(wù),就會(huì)回滾,就大錯(cuò)特錯(cuò)了,今天就來(lái)了解一下吧。

一、@Transactional 屬性介紹

1.事務(wù)的傳播行為:propagation

這就是我們常說(shuō)的事務(wù)的七種傳播行為,默認(rèn)值:Propagation.REQUIRED

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

2.事務(wù)的隔離級(jí)別:isolation

這就是我們常說(shuō)的事務(wù)的隔離級(jí)別,默認(rèn)值:Isolation.DEFAULT

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

3.事務(wù)的超時(shí)時(shí)間:timeout

  • timeout :事務(wù)的超時(shí)時(shí)間,默認(rèn)值為 -1。如果超過(guò)該時(shí)間限制但事務(wù)還沒(méi)有完成,則自動(dòng)回滾事務(wù)。

4.事務(wù)的回滾類型:rollbackFor

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

二、@Transactional 失效場(chǎng)景

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

場(chǎng)景重現(xiàn):當(dāng)調(diào)用 saveCabinet 方法時(shí),save 方法中出異常不會(huì)回滾,如下代碼

@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;	// 模擬出錯(cuò)
    }
}

原因分析:spring 中采用動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)事務(wù),當(dāng)同一個(gè)類調(diào)用 save 時(shí),不是代理類在調(diào)用,所以掃描不到事務(wù)注解

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

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

解決方案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;	// 模擬出錯(cuò)
    }
}

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

場(chǎng)景重現(xiàn):當(dāng)調(diào)用 saveCabinet 方法時(shí),方法體被 try-catch 了,不會(huì)回滾,如下代碼

@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;	// 模擬出錯(cuò)
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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

解決方案:將 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;	// 模擬出錯(cuò)
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e);
        }
    }
}

3.@Transactional 應(yīng)用在非 public 修飾的方法上

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

4.@Transactional 注解屬性 rollbackFor 設(shè)置錯(cuò)誤

場(chǎng)景重現(xiàn):當(dāng)注解沒(méi)有指定 rollbackFor 屬性時(shí),如下若拋出 FileNotFoundException 異常則不會(huì)回滾

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

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

解決方案:指定 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);
        // 模擬出錯(cuò)
        throw new FileNotFoundException();
    }
}

5.@Transactional 注解屬性 propagation 設(shè)置錯(cuò)誤

  • 使用了不支持事務(wù)的傳播屬性

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

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

總結(jié)

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

相關(guān)文章

  • SpringBoot排除自動(dòng)加載數(shù)據(jù)源方式

    SpringBoot排除自動(dòng)加載數(shù)據(jù)源方式

    這篇文章主要介紹了SpringBoot排除自動(dòng)加載數(shù)據(jù)源方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 將本地SpringBoot項(xiàng)目發(fā)布到云服務(wù)器的方法

    將本地SpringBoot項(xiàng)目發(fā)布到云服務(wù)器的方法

    這篇文章主要介紹了如何將本地SpringBoot項(xiàng)目發(fā)布到云服務(wù)器,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • SpringCache快速使用及入門(mén)案例

    SpringCache快速使用及入門(mén)案例

    Spring Cache 是Spring 提供的一整套的緩存解決方案,它不是具體的緩存實(shí)現(xiàn),本文主要介紹了SpringCache快速使用及入門(mén)案例,感興趣的可以了解一下
    2023-08-08
  • Java中List排序的3種常見(jiàn)方法總結(jié)

    Java中List排序的3種常見(jiàn)方法總結(jié)

    在Java編程中List對(duì)象的排序是一個(gè)常見(jiàn)的需求,List接口提供了多種排序方法,這篇文章主要給大家介紹了關(guān)于Java中List排序的3種常見(jiàn)方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • SpringMVC整合SSM實(shí)現(xiàn)表現(xiàn)層數(shù)據(jù)封裝詳解

    SpringMVC整合SSM實(shí)現(xiàn)表現(xiàn)層數(shù)據(jù)封裝詳解

    這篇文章主要介紹了SpringMVC整合SSM實(shí)現(xiàn)表現(xiàn)層數(shù)據(jù)封裝,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-10-10
  • spring整合shiro框架的實(shí)現(xiàn)步驟記錄

    spring整合shiro框架的實(shí)現(xiàn)步驟記錄

    Shiro是一個(gè)強(qiáng)大易用的Java安全框架,提供了認(rèn)證、授權(quán)、加密和會(huì)話管理等功能。下面這篇文章主要給大家介紹了關(guān)于spring整合shiro框架的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-05-05
  • java多線程之并發(fā)工具類CountDownLatch,CyclicBarrier和Semaphore

    java多線程之并發(fā)工具類CountDownLatch,CyclicBarrier和Semaphore

    這篇文章主要為大家介紹了java并發(fā)工具類CountDownLatch,CyclicBarrier和Semaphore ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • Java靜態(tài)代碼塊作用及執(zhí)行順序解析

    Java靜態(tài)代碼塊作用及執(zhí)行順序解析

    這篇文章主要介紹了Java靜態(tài)代碼塊作用及執(zhí)行順序解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Spring mvc攔截器實(shí)現(xiàn)原理解析

    Spring mvc攔截器實(shí)現(xiàn)原理解析

    這篇文章主要介紹了Spring mvc攔截器實(shí)現(xiàn)原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • java web中 HttpClient模擬瀏覽器登錄后發(fā)起請(qǐng)求

    java web中 HttpClient模擬瀏覽器登錄后發(fā)起請(qǐng)求

    這篇文章主要介紹了java web中 HttpClient模擬瀏覽器登錄后發(fā)起請(qǐng)求的相關(guān)資料,需要的朋友可以參考下
    2017-05-05

最新評(píng)論