1. 程式人生 > 實用技巧 >Spring 事務傳播行為

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)

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


連結:https://www.jianshu.com/p/9637196d6b96