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

Spring?@Transactional?注解從入門到避坑指南

 更新時(shí)間:2026年05月06日 10:43:35   作者:ffqws_  
文章主要講解了Spring的@Transactional注解的使用場(chǎng)景、核心屬性詳解、事務(wù)傳播行為、隔離級(jí)別、回滾配置、底層原理以及失效場(chǎng)景和避免之道,并還給出了最佳實(shí)踐,感興趣的朋友跟隨小編一起看看吧

一、為什么需要事務(wù)?

想象一個(gè)下單場(chǎng)景:

  1. 創(chuàng)建訂單
  2. 扣減庫(kù)存
  3. 扣除用戶余額

如果第2步成功了,第3步失敗,庫(kù)存已經(jīng)扣了但錢沒(méi)扣,數(shù)據(jù)就亂了。事務(wù)的作用就是保證這一組操作要么全成功,要么全失敗。

二、快速使用

@Service
public class OrderService {
    @Transactional
    public void submitOrder(OrdersSubmitDTO dto) {
        orderMapper.insert(order);           // 插入訂單
        orderDetailMapper.insertBatch(list); // 插入明細(xì)
        shoppingCartMapper.clean(userId);    // 清空購(gòu)物車
    }
}

加了這個(gè)注解,方法內(nèi)所有數(shù)據(jù)庫(kù)操作會(huì)被包裝在一個(gè)事務(wù)中。任意一步拋異常,Spring 會(huì)自動(dòng)回滾。

三、核心屬性詳解

屬性作用常用值
propagation事務(wù)傳播行為REQUIRED(默認(rèn))、REQUIRES_NEW
isolation隔離級(jí)別READ_COMMITTED、REPEATABLE_READ
rollbackFor指定回滾的異常類型Exception.class
noRollbackFor指定不回滾的異常IllegalArgumentException.class
timeout事務(wù)超時(shí)時(shí)間(秒)-1(默認(rèn)無(wú)限制)
readOnly是否為只讀事務(wù)true / false

3.1 propagation 傳播行為

@Transactional(propagation = Propagation.REQUIRED)  // 默認(rèn)
public void methodA() {
    // 如果已有事務(wù),加入;沒(méi)有則新建
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {
    // 掛起當(dāng)前事務(wù),新建一個(gè)獨(dú)立事務(wù)
}

常見(jiàn)場(chǎng)景:日志記錄必須保存,不管主業(yè)務(wù)是否回滾。此時(shí)日志方法用 REQUIRES_NEW,主業(yè)務(wù)回滾不影響日志。

3.2 isolation 隔離級(jí)別

@Transactional(isolation = Isolation.READ_COMMITTED)
隔離級(jí)別臟讀不可重復(fù)讀幻讀
READ_UNCOMMITTED???
READ_COMMITTED???
REPEATABLE_READ???
SERIALIZABLE???

MySQL 默認(rèn) REPEATABLE_READ,Spring 默認(rèn)跟隨數(shù)據(jù)庫(kù)。

3.3 rollbackFor 回滾配置

重點(diǎn):默認(rèn)只回滾 RuntimeException 和 Error。

// 錯(cuò)誤示范:IOException 不會(huì)觸發(fā)回滾!
@Transactional
public void pay() throws IOException {
    // ...
}
// 正確配置:回滾所有異常
@Transactional(rollbackFor = Exception.class)
public void pay() throws IOException {
    // ...
}

四、底層原理(簡(jiǎn)述)

Spring 通過(guò) AOP 動(dòng)態(tài)代理 實(shí)現(xiàn)事務(wù):

  1. 運(yùn)行時(shí)生成目標(biāo)類的代理對(duì)象
  2. 方法執(zhí)行前開(kāi)啟事務(wù)(begin
  3. 方法正常結(jié)束則提交(commit
  4. 方法拋異常則回滾(rollback

這也是為什么同類內(nèi)部調(diào)用會(huì)導(dǎo)致事務(wù)失效——繞過(guò)了代理對(duì)象。

五、失效場(chǎng)景全解析(避坑指南)

場(chǎng)景 1:同類內(nèi)部調(diào)用(最高頻)

@Service
public class OrderService {
    public void createOrder() {
        saveOrder(); // 直接調(diào)用,事務(wù)失效!
    }
    @Transactional
    public void saveOrder() {
        // ...
    }
}

原因this.saveOrder() 沒(méi)有走代理對(duì)象。

解決

@Autowired
private OrderService orderService;
public void createOrder() {
    orderService.saveOrder(); // 通過(guò)注入的代理調(diào)用
}

場(chǎng)景 2:異常被吞掉

@Transactional
public void submit() {
    try {
        orderMapper.insert(order);
        payService.pay(); // 拋異常
    } catch (Exception e) {
        log.error("支付失敗", e);
        // 異常沒(méi)拋出去,Spring 認(rèn)為成功,提交事務(wù)!
    }
}

解決

} catch (Exception e) {
    throw new RuntimeException(e);
    // 或者手動(dòng)回滾:
    // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}

場(chǎng)景 3:異常類型不匹配

如 3.3 所述,受檢異常(IOException、SQLException)默認(rèn)不回滾。

場(chǎng)景 4:方法非 public

@Transactional 只能作用于 public 方法。

場(chǎng)景 5:數(shù)據(jù)庫(kù)引擎不支持

MySQL 的 MyISAM 引擎不支持事務(wù),表必須是 InnoDB。

六、最佳實(shí)踐

  1. 盡量放在 Service 層,不要在 Controller 或 Mapper 上加
  2. 事務(wù)方法盡量精簡(jiǎn),避免長(zhǎng)事務(wù)(大事務(wù)會(huì)鎖表、拖垮性能)
  3. 查詢操作加 readOnly = true
  4. 明確指定 rollbackFor = Exception.class,避免受檢異常漏網(wǎng)
  5. 不要在事務(wù)里調(diào)外部 HTTP 接口,會(huì)拉長(zhǎng)事務(wù)時(shí)間

七、總結(jié)

要點(diǎn)記憶口訣
代理調(diào)用才生效同類 this. 調(diào)用要警惕
異常必須拋出去別在 catch 里默默吞掉
回滾范圍要明確rollbackFor = Exception.class
長(zhǎng)事務(wù)是性能殺手查詢加 readOnly,事務(wù)盡量短

到此這篇關(guān)于Spring @Transactional 注解詳解:從入門到避坑的文章就介紹到這了,更多相關(guān)Spring @Transactional 注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題

    SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題

    這篇文章主要介紹了SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Mybatis使用useGeneratedKeys獲取自增主鍵

    Mybatis使用useGeneratedKeys獲取自增主鍵

    這篇文章主要為大家介紹了Mybatis使用useGeneratedKeys獲取自增主鍵示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Java多維數(shù)組和Arrays類方法總結(jié)詳解

    Java多維數(shù)組和Arrays類方法總結(jié)詳解

    這篇文章主要介紹了Java多維數(shù)組和Arrays類方法總結(jié)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • SpringBoot3實(shí)現(xiàn)Gzip壓縮優(yōu)化的技術(shù)指南

    SpringBoot3實(shí)現(xiàn)Gzip壓縮優(yōu)化的技術(shù)指南

    隨著 Web 應(yīng)用的用戶量和數(shù)據(jù)量增加,網(wǎng)絡(luò)帶寬和頁(yè)面加載速度逐漸成為瓶頸,為了減少數(shù)據(jù)傳輸量,提高用戶體驗(yàn),我們可以使用 Gzip 壓縮 HTTP 響應(yīng),本文將介紹如何在 Spring Boot 3 中實(shí)現(xiàn) Gzip 壓縮優(yōu)化,需要的朋友可以參考下
    2025-04-04
  • 探究MyBatis插件原理以及自定義插件實(shí)現(xiàn)

    探究MyBatis插件原理以及自定義插件實(shí)現(xiàn)

    這篇文章主要介紹了探究MyBatis插件原理以及自定義插件實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • 方法參數(shù)屬性params,@PathVariable和@RequestParam用法及區(qū)別

    方法參數(shù)屬性params,@PathVariable和@RequestParam用法及區(qū)別

    這篇文章主要介紹了方法參數(shù)屬性params,@PathVariable和@RequestParam用法及區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Java的關(guān)鍵字與標(biāo)識(shí)符小結(jié)

    Java的關(guān)鍵字與標(biāo)識(shí)符小結(jié)

    這篇文章主要介紹了Java的關(guān)鍵字與標(biāo)識(shí)符,總結(jié)整理了Java各種常見(jiàn)的關(guān)鍵字與標(biāo)識(shí)符功能、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • MyBatis-Plus注解配置、條件構(gòu)造器與自定義SQL的復(fù)雜操作實(shí)例詳解

    MyBatis-Plus注解配置、條件構(gòu)造器與自定義SQL的復(fù)雜操作實(shí)例詳解

    MyBatis-Plus是一個(gè)MyBatis的增強(qiáng)工具,提供快速開(kāi)發(fā)單表CRUD操作等功能,通過(guò)依賴引入和配置,可以快速創(chuàng)建和使用Mapper接口進(jìn)行數(shù)據(jù)庫(kù)操作,這篇文章通過(guò)實(shí)例代碼介紹MyBatis-Plus注解配置、條件構(gòu)造器與自定義SQL的復(fù)雜操作,感興趣的朋友一起看看吧
    2026-02-02
  • Java 實(shí)現(xiàn)repalceAll只替換第二個(gè)匹配到的字符串

    Java 實(shí)現(xiàn)repalceAll只替換第二個(gè)匹配到的字符串

    這篇文章主要介紹了Java 實(shí)現(xiàn)repalceAll只替換第二個(gè)匹配到的字符串,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • 使用maven創(chuàng)建web項(xiàng)目的方法步驟(圖文)

    使用maven創(chuàng)建web項(xiàng)目的方法步驟(圖文)

    本篇文章主要介紹了使用maven創(chuàng)建web項(xiàng)目的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01

最新評(píng)論

穆棱市| 浑源县| 华阴市| 鱼台县| 焉耆| 达孜县| 肥乡县| 澎湖县| 山东省| 漠河县| 长春市| 阿合奇县| 瑞丽市| 北川| 贵港市| 宾阳县| 巧家县| 曲水县| 宣恩县| 涞水县| 郧西县| 化隆| 边坝县| 宜章县| 明光市| 景泰县| 江油市| 班玛县| 富民县| 鄱阳县| 毕节市| 台湾省| 塔河县| 泸州市| 米林县| 元江| 三河市| 怀宁县| 唐河县| 汕头市| 思茅市|