Spring 框架系列之事務管理

孔乙己學習成長錄發表於2019-02-26

1、事務回顧

(1)、什麼是事務:

事務是邏輯上的一組操作,組成這組操作的各個邏輯單元,要麼一起成功,要麼一起失敗。

(2)、事務特性(ACID)
  • 原子性 :強調事務的不可分割
  • 一致性 :事務的執行的前後資料的完整性保持一致
  • 隔離性 :一個事務執行的過程中,不應該受到其他事務的干擾
  • 永續性 :事務一旦結束,資料就持久到資料庫
(3)、事務併發安全性問題
  • 髒讀 :一個事務讀到了另一個事務的未提交的資料
  • 不可重複讀 :一個事務讀到了另一個事務已經提交的 update 的資料導致多次查詢結果不一致
  • 幻讀 :一個事務讀到了另一個事務已經提交的 insert 的資料導致多次查詢結果不一致
(4)、事務隔離級別
  • 未提交讀 :髒讀,不可重複讀,幻讀都有可能發生
  • 已提交讀 :避免髒讀,但是不可重複讀和幻讀有可能發生
  • 可重複讀 :避免髒讀和不可重複讀,但是幻讀有可能發生
  • 序列化 :避免以上所有讀問題
(5)、常見資料庫預設事務隔離級別
  • MySQL:可重複讀
  • Oracle:讀已提交

2、Spring 事務管理

(1)、基本事務操作
  • 開啟事務
  • 提交事務
  • 回滾事務
(2)、事務操作物件

Spring 事務管理中提供了 PlatformTransactionManager 介面操作事務,其中最為核心的物件是 TransactionManager 物件。

(3)、Spring 事務隔離級別
  • 讀未提交
  • 讀已提交
  • 可重複讀
  • 序列化
(4)、Spring 事務傳播行為

保證同一個事務中

  • PROPAGATION_REQUIRED :支援當前事務,如果不存在 就新建一個(預設)
  • PROPAGATION_SUPPORTS :支援當前事務,如果不存在,就不使用事務
  • PROPAGATION_MANDATORY :支援當前事務,如果不存在,丟擲異常

保證不在同一個事務中

  • PROPAGATION_REQUIRES_NEW :如果有事務存在,掛起當前事務,建立一個新的事務
  • PROPAGATION_NOT_SUPPORTED :以非事務方式執行,如果有事務存在,掛起當前事務
  • PROPAGATION_NEVER :以非事務方式執行,如果有事務存在,丟擲異常
  • PROPAGATION_NESTED :如果當前事務存在,則巢狀事務執行

3、Spring 事務管理方式

(1)、編碼式
  • 將核心事務管理器配置到 Spring 容器
<!-- 事務核心管理器,封裝了所有事務操作. 依賴於連線池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
    <property name="dataSource" ref="dataSource" ></property>
</bean>
複製程式碼
  • 配置TransactionTemplate模板
<!-- 事務模板物件 -->
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" >
    <property name="transactionManager" ref="transactionManager" ></property>
</bean>
複製程式碼
  • 將事務模板注入Service
<!-- 將 demoDao 和事務模板注入 Service-->
<bean name="demoService" class="com.spring.service.demoServiceImpl" >
    <property name="dm" ref="demoDao" ></property>
    <property name="tt" ref="transactionTemplate" ></property>
</bean>  
複製程式碼
  • 在Service中呼叫模板
(2)、xml 配置方式
  • 匯入所需要的 jar 包和約束

  • 配置事務通知

<!-- 配置事務通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager" >
    <tx:attributes>
        <!-- 以方法為單位,指定方法應用什麼事務屬性
            isolation:隔離級別
            propagation:傳播行為
            read-only:是否只讀
         -->
        <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
        <tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
        <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
        <tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
        <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
        <tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
        <tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
        <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
        <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
    </tx:attributes>
</tx:advice>
複製程式碼
  • 將通知織入目標
<!-- 配置織入 -->
<aop:config  >
    <!-- 配置切點表示式 -->
    <aop:pointcut expression="execution(*com.spring.service.*ServiceImpl.*(..))" id="txPc"/>
    <!-- 配置切面 : 通知+切點
            advice-ref:通知的名稱
            pointcut-ref:切點的名稱
     -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc" />
</aop:config>
複製程式碼
(3)、註解配置方式
  • 匯入所需要的 jar 包和約束

  • 開啟註解管理事務

<!-- 開啟使用註解管理事務 -->
<tx:annotation-driven/>
複製程式碼
  • 在具體業務中使用註解

                         掃描關注微信公眾號,瞭解更多

                               Spring 框架系列之事務管理


相關文章