輕鬆瞭解Spring的事務特性

Spring事務特性:

Spring的特色之一,簡單而強大的事務管理功能,包括編程式事務和聲明式事務。

  1. Spring中涉及到事務管理的API有100多個,核心的只有三個: TransactionDefinition、PlatformTransactionManager、TransactionStatus。所謂事務管理,其實就是“按照給定的事務規則來執行提交或者回滾操作”。“給定的事務規則”就是用 TransactionDefinition 表示的,“按照……來執行提交或者回滾操作”便是用 PlatformTransactionManager 來表示,而 TransactionStatus 用於表示一個運行着的事務的狀態。
  2. TransactionDefinition, 該接口在前面已經介紹過,它用於定義一個事務。它包含了事務的靜態屬性,比如:事務傳播行爲、超時時間等等。Spring 爲我們提供了一個默認的實現類:DefaultTransactionDefinition,該類適用於大多數情況。如果該類不能滿足需求,可以通過實現 TransactionDefinition 接口來實現自己的事務定義。
  3. PlatformTransactionManager 用於執行具體的事務操作。

Public interface PlatformTransactionManager{

TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

void commit(TransactionStatus status)throws TransactionException;

void rollback(TransactionStatus status)throws TransactionException;

}

根據底層所使用的不同的持久化 API 或框架,PlatformTransactionManager 的主要實現類大致如下:

  • DataSourceTransactionManager :適用於使用JDBC和iBatis進行數據持久化操作的情況。
  • HibernateTransactionManager :適用於使用Hibernate進行數據持久化操作的情況。
  • JpaTransactionManager :適用於使用JPA進行數據持久化操作的情況。
  • 另外還有JtaTransactionManager 、JdoTransactionManager、JmsTransactionManager等等。

編程式事務需要你在代碼中直接加入處理事務的邏輯,可能需要在代碼中顯式調用beginTransaction()、commit()、rollback()等事務管理相關的方法,如在執行a方法時候需要事務處理,你需要在a方法開始時候開啓事務,處理完後。在方法結束時候,關閉事務.

聲明式的事務的做法是在a方法外圍添加註解或者直接在配置文件中定義,a方法需要事務處理,在spring中會通過配置文 件在a方法前後攔截,並添加事務.

二者區別.編程式事務侵入性比較強,但處理粒度更細.

相當於一個是手動事務,另一個是系統自動事務。

編程式事務就是需要手工寫代碼提交事務,回滾事務等。聲明性事務就是在配置文件裏面定義一下什麼時候需要事務,到時候系統會自動commit,出異常了自動rollback,不需要在代碼裏面寫commit或者rollback。

 

事務屬性的種類: 傳播行爲、隔離級別、只讀和事務超時

  • a) 傳播行爲定義了被調用方法的事務邊界。
傳播行爲 意義
PROPERGATION_MANDATORY 表示方法必須運行在一個事務中,如果當前事務不存在,就拋出異常
PROPAGATION_NESTED 表示如果當前事務存在,則方法應該運行在一個嵌套事務中。否則,它看起來和PROPAGATION_REQUIRED 看起來沒什麼倆樣
PROPAGATION_NEVER 表示方法不能運行在一個事務中,否則拋出異常
PROPAGATION_NOT_SUPPORTED 表示方法不能運行在一個事務中,如果當前存在一個事務,則該方法將被掛起
PROPAGATION_REQUIRED 表示當前方法必須運行在一個事務中,如果當前存在一個事務,那麼該方法運行在這個事務中,否則,將創建一個新的事務
PROPAGATION_REQUIRES_NEW 表示當前方法必須運行在自己的事務中,如果當前存在一個事務,那麼這個事務將在該方法運行期間被掛起
PROPAGATION_SUPPORTS 表示當前方法不需要運行在一個是事務中,但如果有一個事務已經存在,該方法也可以運行在這個事務中
  • b) 隔離級別

在操作數據時可能帶來 3 個副作用,分別是髒讀、不可重複讀、幻讀。爲了避免這 3 中副作用的發生,在標準的 SQL 語句中定義了 4 種隔離級別,分別是未提交讀、已提交讀、可重複讀、可序列化。而在 spring 事務中提供了 5 種隔離級別來對應在 SQL 中定義的 4 種隔離級別,如下:

隔離級別 意義
ISOLATION_DEFAULT 使用後端數據庫默認的隔離級別
ISOLATION_READ_UNCOMMITTED 允許讀取未提交的數據(對應未提交讀),可能導致髒讀、不可重複讀、幻讀
ISOLATION_READ_COMMITTED 允許在一個事務中讀取另一個已經提交的事務中的數據(對應已提交讀)。可以避免髒讀,但是無法避免不可重複讀和幻讀
ISOLATION_REPEATABLE_READ 一個事務不可能更新由另一個事務修改但尚未提交(回滾)的數據(對應可重複讀)。可以避免髒讀和不可重複讀,但無法避免幻讀
ISOLATION_SERIALIZABLE 這種隔離級別是所有的事務都在一個執行隊列中,依次順序執行,而不是並行(對應可序列化)。可以避免髒讀、不可重複讀、幻讀。但是這種隔離級別效率很低,因此,除非必須,否則不建議使用。
  • c) 只讀

    如果在一個事務中所有關於數據庫的操作都是隻讀的,也就是說,這些操作只讀取數據庫中的數據,而並不更新數據,那麼應將事務設爲只讀模式( READ_ONLY_MARKER ) , 這樣更有利於數據庫進行優化 。

    因爲只讀的優化措施是事務啓動後由數據庫實施的,因此,只有將那些具有可能啓動新事務的傳播行爲(PROPAGATION_NESTED 、 PROPAGATION_REQUIRED 、 PROPAGATION_REQUIRED_NEW) 的方法的事務標記成只讀纔有意義。

    如果使用 Hibernate 作爲持久化機制,那麼將事務標記爲只讀後,會將 Hibernate 的 flush 模式設置爲 FULSH_NEVER, 以告訴 Hibernate 避免和數據庫之間進行不必要的同步,並將所有更新延遲到事務結束。

  • d) 事務超時

    如果一個事務長時間運行,這時爲了儘量避免浪費系統資源,應爲這個事務設置一個有效時間,使其等待數秒後自動回滾。與設

    置“只讀”屬性一樣,事務有效屬性也需要給那些具有可能啓動新事物的傳播行爲的方法的事務標記成只讀纔有意義。

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