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

SpringBoot 中的 @Transactional 事務(wù)基本作用及注意事項(xiàng)示例詳解

 更新時(shí)間:2025年09月25日 10:03:35   作者:喝汽水的貓^  
@Transactional是SpringBoot中聲明式事務(wù)管理的核心注解,通過(guò)注解簡(jiǎn)化事務(wù)控制,確保操作的原子性,支持異?;貪L、隔離級(jí)別和傳播行為配置,需注意代理模式、異常拋出及數(shù)據(jù)庫(kù)支持等條件,避免事務(wù)失效,本文介紹SpringBoot @Transactional事務(wù)作用,感興趣的朋友一起看看吧

前言

@Transactional 是 Spring 中用于聲明式事務(wù)管理的核心注解,它可以簡(jiǎn)化事務(wù)控制邏輯,通過(guò)注解方式替代傳統(tǒng)的編程式事務(wù)管理。在 Spring Boot 中,@Transactional 的使用尤為廣泛,以下是其詳細(xì)解析:

一、基本作用

@Transactional 用于標(biāo)記某個(gè)方法或類需要被事務(wù)管理,Spring 會(huì)在方法執(zhí)行前后自動(dòng)開(kāi)啟、提交或回滾事務(wù),確保操作的原子性(要么全成功,要么全失?。?/p>

使用位置:

  • 方法上:僅對(duì)該方法生效
  • 類上:對(duì)類中所有公共方法生效(public)
  • 接口上:不推薦(可能因代理模式導(dǎo)致失效)

二、核心屬性

@Transactional 有多個(gè)屬性可配置,常用的包括:

屬性名作用默認(rèn)值
rollbackFor指定哪些異常觸發(fā)回滾(類或數(shù)組)僅 RuntimeException 及其子類
noRollbackFor指定哪些異常不觸發(fā)回滾無(wú)
isolation事務(wù)隔離級(jí)別(控制并發(fā)數(shù)據(jù)可見(jiàn)性)Isolation.DEFAULT(數(shù)據(jù)庫(kù)默認(rèn))
propagation事務(wù)傳播行為(控制嵌套方法的事務(wù)歸屬)Propagation.REQUIRED
readOnly是否為只讀事務(wù)(優(yōu)化性能,適合查詢操作)false
timeout事務(wù)超時(shí)時(shí)間(秒),超時(shí)后自動(dòng)回滾-1(無(wú)超時(shí))
value/transactionManager指定事務(wù)管理器(多數(shù)據(jù)源時(shí)使用)默認(rèn)事務(wù)管理器

1. 異?;貪L配置(rollbackFor/noRollbackFor)

  • 默認(rèn)規(guī)則:僅對(duì) RuntimeException 及其子類(非檢查異常)回滾,對(duì) Exception 及其子類(檢查異常)不回滾。
  • 推薦配置:rollbackFor = Exception.class,確保所有異常都觸發(fā)回滾:

示例:

@Transactional(rollbackFor = Exception.class) // 所有異常都回滾
public void saveData() throws Exception {
    // 業(yè)務(wù)邏輯
}
  • 特殊需求:指定不回滾的異常:

示例:

@Transactional(noRollbackFor = ArithmeticException.class)
public void process() {
    // 發(fā)生 ArithmeticException 不回滾,其他異常正常回滾
}

2. 隔離級(jí)別(isolation)

控制并發(fā)事務(wù)之間的數(shù)據(jù)可見(jiàn)性,可選值:

  • Isolation.DEFAULT:使用數(shù)據(jù)庫(kù)默認(rèn)隔離級(jí)別(推薦)
  • Isolation.READ_UNCOMMITTED:讀未提交(最低隔離,可能臟讀)
  • Isolation.READ_COMMITTED:讀已提交(避免臟讀,多數(shù)數(shù)據(jù)庫(kù)默認(rèn))
  • Isolation.REPEATABLE_READ:可重復(fù)讀(避免臟讀、不可重復(fù)讀,MySQL 默認(rèn))
  • Isolation.SERIALIZABLE:串行化(最高隔離,避免幻讀,性能最低)

示例:

@Transactional(isolation = Isolation.READ_COMMITTED)
public void queryData() {
    // 事務(wù)內(nèi)查詢,只能看到已提交的數(shù)據(jù)
}

3.臟讀(Dirty Read)

定義:一個(gè)事務(wù)讀取到了另一個(gè)未提交事務(wù)修改的數(shù)據(jù)。

場(chǎng)景示例:

  • 事務(wù) A:更新了一條記錄但未提交
  • 事務(wù) B:讀取了事務(wù) A 更新后的記錄
  • 事務(wù) A:由于某種原因回滾了操作
  • 結(jié)果:事務(wù) B 讀取到的數(shù)據(jù)是 “無(wú)效” 的(已被回滾)

危害:導(dǎo)致讀取到臨時(shí)且可能被撤銷的數(shù)據(jù),影響業(yè)務(wù)邏輯正確性。

避免方式:將事務(wù)隔離級(jí)別設(shè)置為 READ COMMITTED 或更高(REPEATABLE READ、SERIALIZABLE)。

MySQL 默認(rèn)隔離級(jí)別是 REPEATABLE READ,已避免臟讀。

4.幻讀(Phantom Read)

定義:一個(gè)事務(wù)在兩次查詢中得到不同的結(jié)果集,因?yàn)榱硪粋€(gè)事務(wù)在兩次查詢之間插入或刪除了數(shù)據(jù)。

場(chǎng)景示例:

  • 事務(wù) A:查詢年齡 > 20 的用戶,得到 10 條記錄
  • 事務(wù) B:插入了一條年齡 = 25 的新用戶并提交
  • 事務(wù) A:再次執(zhí)行相同查詢,得到 11 條記錄(多了一條 “幻影” 數(shù)據(jù))

5. 傳播行為(propagation)

控制嵌套方法的事務(wù)歸屬,核心值:

  • Propagation.REQUIRED(默認(rèn)):如果當(dāng)前有事務(wù),則加入;否則新建事務(wù)。
  • Propagation.REQUIRES_NEW:無(wú)論當(dāng)前是否有事務(wù),都新建獨(dú)立事務(wù)(原事務(wù)暫停)。
  • Propagation.SUPPORTS:如果當(dāng)前有事務(wù),則加入;否則以非事務(wù)方式執(zhí)行。
  • Propagation.NOT_SUPPORTED:以非事務(wù)方式執(zhí)行,若當(dāng)前有事務(wù)則暫停。
  • Propagation.NEVER:必須在非事務(wù)環(huán)境執(zhí)行,否則拋異常。
  • Propagation.MANDATORY:必須在事務(wù)環(huán)境執(zhí)行,否則拋異常。
  • Propagation.NESTED:嵌套事務(wù)(依賴數(shù)據(jù)庫(kù)支持,如 MySQL 的 SAVEPOINT)。

示例:獨(dú)立事務(wù)場(chǎng)景

@Service
public class OrderService {
    @Autowired
    private LogService logService;
    @Transactional(rollbackFor = Exception.class)
    public void createOrder() {
        // 訂單業(yè)務(wù)(主事務(wù))
        logService.saveLog(); // 調(diào)用日志服務(wù)
    }
}
@Service
public class LogService {
    // 日志保存使用獨(dú)立事務(wù),即使訂單回滾,日志仍會(huì)提交
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void saveLog() {
        // 保存日志
    }
}

6. 其他屬性

  • readOnly = true:適用于純查詢方法,數(shù)據(jù)庫(kù)可優(yōu)化性能(如避免寫(xiě)鎖):
@Transactional(readOnly = true)
public List<User> queryUsers() {
    return userMapper.selectAll();
}
  • timeout = 10:事務(wù)超時(shí)時(shí)間 10 秒,超時(shí)后自動(dòng)回滾:
@Transactional(timeout = 10)
public void longTimeTask() {
    // 長(zhǎng)時(shí)間任務(wù),超時(shí)會(huì)回滾
}

三、事務(wù)生效條件

1.代理模式:Spring 事務(wù)基于 AOP 代理實(shí)現(xiàn),需滿足:

  • 方法必須是 public(非 public 方法注解可能失效)。
  • 需通過(guò) Spring 容器的代理對(duì)象調(diào)用方法(同類中自調(diào)用可能失效,需特殊處理)。

2.異常處理:

  • 異常必須拋出到 @Transactional 標(biāo)記的方法外(被捕獲的異常不會(huì)觸發(fā)回滾)。
  • 需符合 rollbackFor 配置的異常類型。

3.數(shù)據(jù)庫(kù)支持:

  • 數(shù)據(jù)庫(kù)必須支持事務(wù)(如 MySQL 的 InnoDB 引擎,MyISAM 不支持)。

四、常見(jiàn)問(wèn)題

1.自調(diào)用事務(wù)失效:

@Service
public class UserService {
    public void methodA() {
        methodB(); // 自調(diào)用,事務(wù)可能失效
    }
    @Transactional
    public void methodB() {
        // 業(yè)務(wù)邏輯
    }
}

解決:通過(guò) Spring 上下文獲取代理對(duì)象調(diào)用,或使用 @EnableAspectJAutoProxy(exposeProxy = true) 暴露代理。

2.多線程事務(wù)不共享:

新線程中的方法不會(huì)加入當(dāng)前事務(wù),需手動(dòng)協(xié)調(diào)事務(wù)。

3.錯(cuò)誤的異常處理:

@Transactional
public void save() {
    try {
        // 業(yè)務(wù)邏輯
    } catch (Exception e) {
        // 異常被捕獲,未拋出,事務(wù)不會(huì)回滾
    }
}

解決:捕獲后需重新拋出異常,或手動(dòng)調(diào)用 TransactionStatus.setRollbackOnly()。

五、總結(jié)

@Transactional 是 Spring Boot 中簡(jiǎn)化事務(wù)管理的強(qiáng)大工具,核心關(guān)注:

  • 異?;貪L規(guī)則(rollbackFor)
  • 并發(fā)控制(isolation)
  • 嵌套事務(wù)關(guān)系(propagation)
    合理配置可確保數(shù)據(jù)一致性,同時(shí)需注意代理模式、異常處理等細(xì)節(jié)避免事務(wù)失效。

到此這篇關(guān)于SpringBoot 中的 @Transactional 事務(wù)詳解及注意事項(xiàng)的文章就介紹到這了,更多相關(guān)SpringBoot @Transactional 事務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • RocketMQ根據(jù)Tag進(jìn)行消息過(guò)濾

    RocketMQ根據(jù)Tag進(jìn)行消息過(guò)濾

    消費(fèi)者訂閱了某個(gè)主題后,Apache RocketMQ 會(huì)將該主題中的所有消息投遞給消費(fèi)者。若消費(fèi)者只需要關(guān)注部分消息,可通過(guò)設(shè)置過(guò)濾條件在 Apache RocketMQ 服務(wù)端進(jìn)行過(guò)濾,只獲取到需要關(guān)注的消息子集,避免接收到大量無(wú)效的消息
    2023-02-02
  • Java SPI簡(jiǎn)單應(yīng)用案例詳解

    Java SPI簡(jiǎn)單應(yīng)用案例詳解

    這篇文章主要介紹了Java SPI簡(jiǎn)單應(yīng)用案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Spring Boot Controller處理HTTP請(qǐng)求體的方法

    Spring Boot Controller處理HTTP請(qǐng)求體的方法

    Spring Boot提供了強(qiáng)大的機(jī)制來(lái)處理不同 Content-Type? 的HTTP請(qǐng)求體,這主要依賴于 HttpMessageConverter? 接口的各種實(shí)現(xiàn),它們能夠自動(dòng)將請(qǐng)求體內(nèi)容轉(zhuǎn)換成Java方法參數(shù),本文給大家介紹Spring Boot Controller處理HTTP請(qǐng)求體的方法,感興趣的朋友一起看看吧
    2025-05-05
  • SpringCloud中的Consul詳解

    SpringCloud中的Consul詳解

    這篇文章主要介紹了SpringCloud中的Consul知識(shí),本文使用的是docker-compose方式管理consul服務(wù),直接啟動(dòng)即可,需要的朋友可以參考下
    2022-03-03
  • Spring Boot構(gòu)建框架詳解

    Spring Boot構(gòu)建框架詳解

    這篇文章主要為大家詳細(xì)介紹了Spring Boot構(gòu)建框架的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Java案例使用集合方法實(shí)現(xiàn)統(tǒng)計(jì)任意字符串中字符出現(xiàn)的次數(shù)

    Java案例使用集合方法實(shí)現(xiàn)統(tǒng)計(jì)任意字符串中字符出現(xiàn)的次數(shù)

    這篇文章主要介紹了Java案例使用集合方法實(shí)現(xiàn)統(tǒng)計(jì)任意字符串中字符出現(xiàn)的次數(shù),下面我們將用兩種方法實(shí)現(xiàn),需要的小伙伴可以參考一下文章具體內(nèi)容
    2022-04-04
  • Java實(shí)現(xiàn)JWT登錄認(rèn)證的示例代碼

    Java實(shí)現(xiàn)JWT登錄認(rèn)證的示例代碼

    Java中我們可以使用諸如JJWT這樣的庫(kù)來(lái)生成和驗(yàn)證JWT,本文主要介紹了Java實(shí)現(xiàn)JWT登錄認(rèn)證的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • SpringMVC的REST風(fēng)格的四種請(qǐng)求方式總結(jié)

    SpringMVC的REST風(fēng)格的四種請(qǐng)求方式總結(jié)

    下面小編就為大家?guī)?lái)一篇SpringMVC的REST風(fēng)格的四種請(qǐng)求方式總結(jié)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 淺談mybatis中的#和$的區(qū)別 以及防止sql注入的方法

    淺談mybatis中的#和$的區(qū)別 以及防止sql注入的方法

    下面小編就為大家?guī)?lái)一篇淺談mybatis中的#和$的區(qū)別 以及防止sql注入的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-10-10
  • Java?Jar包項(xiàng)目?jī)?nèi)存設(shè)置方法舉例

    Java?Jar包項(xiàng)目?jī)?nèi)存設(shè)置方法舉例

    這篇文章主要給大家介紹了關(guān)于Java?Jar包項(xiàng)目?jī)?nèi)存設(shè)置方法的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-01-01

最新評(píng)論