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

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

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

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

想象一個下單場景:

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

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

二、快速使用

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

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

三、核心屬性詳解

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

3.1 propagation 傳播行為

@Transactional(propagation = Propagation.REQUIRED)  // 默認
public void methodA() {
    // 如果已有事務(wù),加入;沒有則新建
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {
    // 掛起當前事務(wù),新建一個獨立事務(wù)
}

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

3.2 isolation 隔離級別

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

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

3.3 rollbackFor 回滾配置

重點:默認只回滾 RuntimeException 和 Error

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

四、底層原理(簡述)

Spring 通過 AOP 動態(tài)代理 實現(xiàn)事務(wù):

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

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

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

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

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

原因this.saveOrder() 沒有走代理對象。

解決

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

場景 2:異常被吞掉

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

解決

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

場景 3:異常類型不匹配

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

場景 4:方法非 public

@Transactional 只能作用于 public 方法。

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

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

六、最佳實踐

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

七、總結(jié)

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

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

相關(guān)文章

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

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

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

    Mybatis使用useGeneratedKeys獲取自增主鍵

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論

陈巴尔虎旗| 上饶市| 镇远县| 乐安县| 梨树县| 财经| 康平县| 贵定县| 重庆市| 阳山县| 旬邑县| 永嘉县| 昂仁县| 云浮市| 新营市| 桂东县| 大石桥市| 容城县| 通江县| 乌鲁木齐县| 抚宁县| 洛隆县| 温州市| 武宣县| 香港| 紫金县| 安图县| 屏南县| 香格里拉县| 高青县| 湘潭县| 余姚市| 安泽县| 江西省| 大连市| 雅安市| 嫩江县| 伽师县| 鹤庆县| 靖西县| 荣成市|