Spring 事務傳播行爲

如果對事務不瞭解的可以先看下,我的上一篇文章: 數據庫事務詳解

概述

一般SSH的項目都是使用三層架構即Controller、Services、DAO。
Spring 的事務一般都在Services定義,而Controller、DAO都不定義事務。
那麼 Services 方法調用 Services 的方法,事務是怎麼執行的?
有些人說不建議Service 調用Service,或者如果要Service 調用Service必須使用嵌套事務。真的是這樣的嗎?

帶着疑問繼續瞭解Spring事務傳播行爲

spring事務定義了7種傳播行爲,傳播行爲有什麼作用?在什麼情況下使用?

Spring 事務傳播行爲

Spring的TransactionDefinition類中定義了7中事務傳播類型,代碼如下:

我們先來假設一個場景
在 ServiceA 中方法 A() 調用 ServiceB 中方法 B()。
Spring 的事務傳播行爲就是解決方法之間的事務傳播的。
基本方法調用場景如下:
* 方法A有事務,方法B也有事務
* 方法A有事務,方法B沒有事務
* 方法A沒有事務,方法B有事務
* 方法A沒有事務,方法B也沒有事務

1. PROPAGATION_REQUIRED

支持當前事務,如果當前沒有事務,就新建一個事務。他也是Spring提供的默認事務傳播行爲,適合絕大數情況。

如果A方法有事務,那麼B方法就使用A方法的事務。
如果A方法沒有事務,那麼B方法就創建一個新事物。

2. PROPAGATION_SUPPORTS

支持當前事務,如果當前沒有事務,就以非事務方式執行。

如果A方法有事務,那麼B方法就使用A方法的事務。
如果A方法沒有事務,那麼B方法就不使用事務的方式執行。

3. PROPAGATION_MANDATORY

支持當前事務,如果當前沒有事務,就拋出異常。

如果A方法有事務,那麼A方法就使用A方法事務。
如果A方法沒有事務,那麼就拋出異常。

該事務傳播行爲要求A方法必須以事務的方式運行

4. PROPAGATION_REQUIRES_NEW

新建事務,如果當前存在事務,把當前事務掛起。

如果A方法有事務,就把A方法的事務掛起,B方法新創建一個事務。
如果A方法沒有事務,那麼B方法就創建一個新事務。

5. PROPAGATION_NOT_SUPPORTED

以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

如果A方法有事務,那麼就把A方法的事務掛起,B方法以非事務的方式執行。
如果A方法沒有事務,那麼B也不使用事務執行。

6. PROPAGATION_NEVER

以非事務方式執行,如果當前存在事務,則拋出異常。

如果方法A有事務,那麼就拋出異常。
如果方法A沒有事務,那麼B方法就以非事務的方式運行。

跟 3. PROPAGATION_MANDATORY 事務傳播行爲相反。

7. PROPAGATION_NESTED

如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的。

如果A方法有事務,那麼B方法就在A方法的事務中使用嵌套事務。
如果A方法沒有事務,那麼方法B就新創建一個事務。

嵌套事務

嵌套事務是使用數據庫的SavePoint(事務保存點)。需要底層數據庫的支持。
如果在Spring使用嵌套事務,需要滿足一下3點。
* 需要數據庫支持。
可以使用以下代碼來判斷數據庫是否支持。

Connection.getMetaData().supportsSavepoints();
  • JDK 1.4 才支持 java.sql.Savepoint 。所以JDK必須在1.4 及以上。

  • 還需要Spring中配置nestedTransactionAllowed=true。
    我們要設置 transactionManager 的 nestedTransactionAllowed 屬性爲 true, 注意, 此屬性默認爲 false!!!

    <bean id="transactionManager"  
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
        <property name="sessionFactory" ref="sessionFactory" />  
        <property name="nestedTransactionAllowed">  
            <value>true</value>  
        </property>  
    </bean> 

只讀事務(Readonly Transaction)

Spring 爲了忽略那些不需要事務的方法,比如讀取數據,這樣可以有效的提高一些性能。

事務超時 (Transaction Timeout)

爲了解決事務執行時間太長,消耗太多資源的問題,可以設置一個超時時間。如果該事務支持超過設置的時間,就回滾該事務。


想了解更多精彩內容請關注我的公衆號

本人簡書blog地址:http://www.jianshu.com/u/1f0067e24ff8    
點擊這裏快速進入簡書

GIT地址:http://git.oschina.net/brucekankan/
點擊這裏快速進入GIT

發佈了132 篇原創文章 · 獲贊 79 · 訪問量 40萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章