首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring 事務屬性 transactionAttributes 詳細配置指南

     編輯:Java 相關知識

transactionAttributes 核心語法

在 TransactionProxyFactoryBean 或父類 Bean 中定義:

<property name="transactionAttributes">
    <props>
        <prop key="insert*">PROPAGATION_REQUIRED,-Exception</prop>
        <prop key="update*">PROPAGATION_REQUIRED,-Exception</prop>
        <prop key="delete*">PROPAGATION_REQUIRED,-Exception</prop>
        <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
        <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    </props>
</property>

格式:方法名模式=傳播行為,隔離級別,只讀標誌,超時,回滾異常規則

七大傳播行為深度解析

常量行為描述典型場景
PROPAGATION_REQUIRED支持當前事務,無則新建(最常用)通用業務方法
PROPAGATION_SUPPORTS支持當前事務,無則非事務執行純查詢、只讀操作
PROPAGATION_MANDATORY必須在事務中執行,無則拋異常強制事務上下文的核心邏輯
PROPAGATION_REQUIRES_NEW掛起當前事務,新建獨立事務日誌記錄、審計、獨立提交
PROPAGATION_NOT_SUPPORTED非事務執行,掛起當前事務長耗時非事務操作、外部 API 呼叫
PROPAGATION_NEVER非事務執行,有事務則拋異常嚴禁事務的場景
PROPAGATION_NESTED嵌套事務(需 JDBC 3.0+ 驅動支援)部分回滾、保存點管理

關鍵修飾符說明

  • -Exception:遇到 Exception(含子類)回滾,+Exception 表示提交
  • readOnly:標註只讀,數據庫可優化鎖策略,Hibernate 可跳過髒檢查
  • timeout_30:超時秒數,超時自動回滾
  • isolation_READ_COMMITTED:隔離級別,預設通常為 READ_COMMITTED

性能優化實戰:查詢方法去事務化

問題:所有方法統用 PROPAGATION_REQUIRED 導致查詢也開啟事務,產生不必要的資料庫鎖與連接持有。

優化:將查詢方法改為 PROPAGATION_NEVER 或 PROPAGATION_SUPPORTS,readOnly

<prop key="query*">PROPAGATION_NEVER</prop>
<prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="count*">PROPAGATION_NEVER</prop>

效果:查詢效率顯著提升,連接池佔用降低。

嵌套調用風險提示

若 saveXxx() 內部調用 queryXxx(),而 query* 配置為 PROPAGATION_NEVER,運行時會拋 IllegalTransactionStateException(存在事務卻要求無事務)。

解決策略:

  1. 查詢方法用 PROPAGATION_SUPPORTS,readOnly 替代 NEVER,兼容有/無事務上下文
  2. 或將內部查詢提取為獨立 Service 方法,配置 REQUIRES_NEW 獨立事務
  3. 代碼重構:Service 層不直接調用 Dao 查詢,而是調用另一個只讀 Service

最佳實踐模板

<bean id="baseTxProxy" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="transactionAttributes">
        <props>
            <!-- 寫操作:必須事務,異常回滾 -->
            <prop key="save*">PROPAGATION_REQUIRED,-Exception</prop>
            <prop key="insert*">PROPAGATION_REQUIRED,-Exception</prop>
            <prop key="update*">PROPAGATION_REQUIRED,-Exception</prop>
            <prop key="delete*">PROPAGATION_REQUIRED,-Exception</prop>
            <prop key="remove*">PROPAGATION_REQUIRED,-Exception</prop>

            <!-- 讀操作:支持事務,只讀優化 -->
            <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
            <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
            <prop key="query*">PROPAGATION_SUPPORTS,readOnly</prop>
            <prop key="count*">PROPAGATION_SUPPORTS,readOnly</prop>
            <prop key="list*">PROPAGATION_SUPPORTS,readOnly</prop>
            <prop key="load*">PROPAGATION_SUPPORTS,readOnly</prop>

            <!-- 特殊:批量導入獨立事務 -->
            <prop key="batch*">PROPAGATION_REQUIRES_NEW,-Exception</prop>
            <!-- 特殊:日誌記錄獨立提交 -->
            <prop key="log*">PROPAGATION_REQUIRES_NEW</prop>
        </props>
    </property>
</bean>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved