Spring 框架系列之事務管理

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/>
  • 在具體業務中使用註解

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章