Spring事務管理分爲編程式事務管理和聲明式事務管理兩種。
編程式事務容許用戶在實現代碼中使用顯式的方式調用beginTransaction()開啓事務、commit()提交事務、rollback()回滾事務,從而能夠達到精肯定義事務的邊界。
聲明式事務管理底層是創建在Spring AOP的基礎上,在方式執行先後進行攔截,並在目標方法開始執行前建立新事務或加入一個已存在事務,最後在目標方法執行完後根據狀況提交或者回滾事務。聲明式事務的最大優勢就是不須要編程,將事務管理從複雜業務邏輯中抽離,只須要在配置文件中配置並在目標方法上添加@Transactional註解便可實現。
Spring事務屬性定義在TransactionDefinition接口中,Spring4中該接口代碼實現以下:編程
public interface TransactionDefinition { int PROPAGATION_REQUIRED = 0; int PROPAGATION_SUPPORTS = 1; int PROPAGATION_MANDATORY = 2; int PROPAGATION_REQUIRES_NEW = 3; int PROPAGATION_NOT_SUPPORTED = 4; int PROPAGATION_NEVER = 5; int PROPAGATION_NESTED = 6; int ISOLATION_DEFAULT = -1; int ISOLATION_READ_UNCOMMITTED = 1; int ISOLATION_READ_COMMITTED = 2; int ISOLATION_REPEATABLE_READ = 4; int ISOLATION_SERIALIZABLE = 8; int TIMEOUT_DEFAULT = -1; //事務的傳播行爲 int getPropagationBehavior(); //事務的隔離級別 int getIsolationLevel(); //事務超時時間 int getTimeout(); //是否只讀 boolean isReadOnly(); String getName(); }
Spring事務屬性能夠就是事務的一些基本配置,描述了事務策略如何應用到方法上面,事務屬性包含如下5個方面:
數組
Spring事務傳播屬性有7種:在事務定義接口TransactionDefinition中定義了7個表示傳播行爲的常量,分別是微信
PROPAGATION_REQUIRED;
PROPAGATION_SUPPORTS;
PROPAGATION_MANDATORY;
PROPAGATION_REQUIRES_NEW;
PROPAGATION_NOT_SUPPORTED;
PROPAGATION_NEVER;
PROPAGATION_NESTED;併發
在方法@Transactional註解時使用以下:
@Transactional(propagation=Propagation.REQUIRED) 若是有事務, 那麼加入事務, 沒有的話新建一個(默認狀況下)
@Transactional(propagation=Propagation.NOT_SUPPORTED)容器不爲這個方法開啓事務@Transactional(propagation=Propagation.REQUIRES_NEW)無論是否存在事務,都建立一個新的事務,原來的掛起,新的執行完畢,繼續執行舊的事務
@Transactional(propagation=Propagation.MANDATORY)必須在一個已有的事務中執行,不然拋出異常
@Transactional(propagation=Propagation.NEVER) 必須在一個沒有的事務執行,不然拋出異常(與Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.SUPPORTS)若是其餘bean調用這個方法,在其餘bean中聲明事務,那就用事務.若是其餘 bean沒有聲明事務,那就不用事務.
詳細描述以下表所示:
框架
Spring事務的隔離級別定義了一個事務可能受到其餘併發事務影響的程度,在事務定義接口TransactionDefinition 中定義了五個表示隔離級別的常量,分別是分佈式
ISOLATION_DEFAULT,
ISOLATION_READ_UNCOMMITTED,
ISOLATION_READ_COMMITTED,
ISOLATION_REPEATABLE_READ,
ISOLATION_SERIALIZABLE;性能
各個隔離級別在Spring中註解方式以下:
@Transactional(isolation = Isolation.READ_UNCOMMITTED)讀取未提交數據(會出現髒讀, 不可重複讀) 基本不使用
@Transactional(isolation = Isolation.READ_COMMITTED)讀取已提交數據(會出現不可重複讀和幻讀)
@Transactional(isolation = Isolation.REPEATABLE_READ)可重複讀(會出現幻讀)
@Transactional(isolation = Isolation.SERIALIZABLE)串行化
@Transactional(isolation = Isolation.DEFAULT)默認級別,MYSQL: 默認爲REPEATABLE_READ級別 SQLSERVER: 默認爲READ_COMMITTED
隔離級別詳細描述以下表
spa
TransactionDefinition 接口中定義了1個表示超時時間的常量TIMEOUT_DEFAULT ,使用getTimeout()方法能夠獲取到超時時間,單位是秒。Spring事務超時時間,是指一個事務所容許執行的最長時間,若是超過該時間限制但事務尚未完成,則自動回滾事務。
在Spring程序中超時時間設置的註解方式是設置timeout的值表示這個事務,true只讀取數據但不更新數據,false表示可正常讀寫數據
@Transactional(timeout=30) 默認是-1,不超時
超時時間詳細描述以下表
設計
事務管理的只讀屬性是指對事務性資源進行只讀操做或者是可讀寫操做。所謂事務性資源就是指那些被事務管理的資源,如數據源、JMS 資源,以及自定義的事務性資源等。若是肯定只對事務性資源進行只讀操做,那麼咱們能夠將事務標誌爲只讀的,以提升事務處理的性能。在TransactionDefinition 中以 boolean 類型來表示該事務是否只讀,使用方法isReadOnly()來判斷事務是不是隻讀的。
事務管理的只讀屬性詳細描述以下
日誌
一般狀況下,若是在事務中拋出了未檢查異常(繼承自 RuntimeException 的異常),則默認將回滾事務。若是沒有拋出任何異常,或者拋出了已檢查異常,則正常提交事務。咱們能夠根據須要人爲控制事務在拋出某些未檢查異常時仍然提交事務,或者在拋出某些已檢查異常時回滾事務。
Transactional註解中有4個屬性經過設置系統異常類和自定義異常類來自定義回滾規則。
4個屬性分別是
rollbackFor,
rollbackForClassName,
noRollbackFor,
noRollbackForClassName
@Transactional(rollbackFor=RuntimeException.class)
用於設置須要進行回滾的異常類數組,當方法中拋出指定異常數組中的異常時,則事務回滾。
@Transactional(rollbackForClassName="RuntimeException")
用於設置須要進行回滾的異常類名稱數組,當方法中拋出指定異常名稱數組中的異常時,則進行事務回滾
@Transactional(noRollbackFor=RuntimeException.class)
用於設置不須要進行回滾的異常類數組,當方法中拋出指定異常數組中的異常時,不進行事務回滾
@Transactional(noRollbackForClassName=RuntimeException.class)
用於設置不須要進行回滾的異常類名稱數組,當方法中拋出指定異常名稱數組中的異常時,不進行事務回滾
在Spring開發中,@Transactional註解的經常使用參數彙總以下
「
本訂閱號提供Java相關技術分享,從Java編程基礎到Java高級技術,從JavaWeb技術基礎Jsp、Servlet、JDBC到SSH、SSM開發框架,從REST風格接口設計到分佈式項目實戰。剖析主流開源技術框架,用親身實踐來譜寫深度Java技術日誌。「