本文摘抄了Spring事務相關的一些理論,主要講述事務的特性、事務的傳播行為、事務的隔離規則。 ...
摘要
本文摘抄了Spring事務相關的一些理論,主要講述事務的特性、事務的傳播行為、事務的隔離規則。
關鍵詞:事務特性,事務傳播,事務隔離
一、什麼是事務
事務是用來保證數據的完整性和一致性,正如金錢轉賬,金錢總數不會增加也不會減少。
資料庫 事務管理有四個特性(ACID):
特性 | 描述 |
---|---|
原子性(Atomicity) | 事務作為一個整體被執行,要麼全部被執行,要麼都不執行。 |
一致性(Consistency) | 事務應確保數據的狀態從一個一致狀態轉變為另一個一致狀態,數據不應該被破壞。 |
隔離性(Isolation) | 多個事務併發執行時,一個事務的執行不應影響其他事務的執行。 |
持久性(Durability) | 已被提交的事務對數據的修改應該永久性的。 |
二、Spring事務管理器
1. 事務管理介面
Spring中定義了事務管理的總介面PlatformTransactionManager,該介面定義了以下幾個介面來管理事務:
- getTransaction() - 獲取事務狀態(TransactionStatus),該事務由(TransactionDefinition定義)
- commit() - 提交事務
- rollback() - 回滾事務
Spring不直接管理事務,而是提供一個事務管理介面,由其他平臺(如JDBC、Hibernate)自己實現事務管理。
幾個具體的事務:
事務名稱 | 管理器類 | 說明 |
---|---|---|
JDBC事務 | org.springframework.jdbc.datasource.DataSourceTransactionManager | 通過調用java.sql.Connection來管理事務 |
Hibernate | org.springframework.orm.hibernate3.HibernateTransactionManager | 事務管理由org.hibernate.Transaction對象負責 |
Java持久化API事務(JPA) | org.springframework.orm.jpa.JpaTransactionManager | JpaTransactionManager與由工廠(javax.persistence.EntityManagerFactory)所產生的JPA EntityManager合作來構建事務 |
Java原生API事務 | org.springframework.transaction.jta.JtaTransactionManager | JtaTransactionManager將事務管理的責任委托給javax.transaction.UserTransaction和javax.transaction.TransactionManager對象(允許在多個資料庫之間管理多個事務) |
關於JTA,參考Java中的事務——JDBC事務和JTA事務
(Spring事務管理器)
2. 事務管理與AOP
Spring通過AOP攔截所有需要事務管理的業務處理方法。
三、Spring事務屬性
Spring事務有幾個屬性,TransactionDefinition介面可以體現出來:
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 = Connection.TRANSACTION_READ_UNCOMMITTED;
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
// 預設超時時間
int TIMEOUT_DEFAULT = -1;
// 獲取事務傳播行為
int getPropagationBehavior();
// 獲取事務隔離級別
int getIsolationLevel();
// 獲取事務超時時間
int getTimeout();
// 獲取事務是否只讀
boolean isReadOnly();
// 獲取事務名字
String getName();
}
介面的定義加上回滾規則,事務可以有以下五個基本配置:事務傳播行為、事務隔離級別、事務超時、事務只讀、回滾規則
1. 傳播行為
所謂傳播行為(propagation behavior)指一個事務方法被另一個事務方法調用時,事務應該如何處理。被調用的方法可能在現有事務中運行,或者啟動一個新的事務,在自己事務內運行。
傳播行為 | 含義 | 解釋 |
---|---|---|
PROPAGATION_REQUIRED | 表示當前方法必須運行在事務中。如果當前事務存在,方法將會在該事務中運行。否則,會啟動一個新的事務 | 有且只有一個事務 |
PROPAGATION_SUPPORTS | 表示當前方法不需要事務上下文,但是如果存在當前事務的話,那麼該方法會在這個事務中運行 | 如果方法單獨調用則是非事務執行,如果方法被另一個有事務的方法調用,被調用方法則加入事務 |
PROPAGATION_MANDATORY | 表示該方法必須在事務中運行,如果當前事務不存在,則會拋出一個異常 | 如果單獨非事務調用會拋異常,必須被其它事務方法調用,加入到事務中。 |
PROPAGATION_REQUIRED_NEW | 表示當前方法必須運行在它自己的事務中。一個新的事務將被啟動。如果存在當前事務,在該方法執行期間,當前事務會被掛起。如果使用JTATransactionManager的話,則需要訪問TransactionManager | 總是開啟一個新的事務,原調用事務存在的話會被掛起,直至事務完成。 |
PROPAGATION_NOT_SUPPORTED | 表示該方法不應該運行在事務中。如果存在當前事務,在該方法運行期間,當前事務將被掛起。如果使用JTATransactionManager的話,則需要訪問TransactionManager | 總是非事務地執行該方法,如果調用事務存在的話會被掛起,直至方法執行完成 |
PROPAGATION_NEVER | 表示當前方法不應該運行在事務上下文中。如果當前正有一個事務在運行,則會拋出異常 | 總是非事務性執行方法,否則拋出異常 |
PROPAGATION_NESTED | 表示如果當前已經存在一個事務,那麼該方法將會在嵌套事務中運行。嵌套的事務可以獨立於當前事務進行單獨地提交或回滾。如果當前事務不存在,那麼其行為與PROPAGATION_REQUIRED一樣。註意各廠商對這種傳播行為的支持是有所差異的。可以參考資源管理器的文檔來確認它們是否支持嵌套事務 | 嵌套事務一個非常重要的概念就是內層事務依賴於外層事務。外層事務失敗時,會回滾內層事務所做的動作。而內層事務操作失敗並不會引起外層事務的回滾。 |
2. 隔離規則
事務的執行會存在併發的,隔離級別定義了一個事務受其它併發事務影響的程度。
有兩個表格:
併發事務引起的問題
問題 | 定義 | 出現原因 |
---|---|---|
臟讀 | 讀到無效的數據 | 當一個事務讀取了另一個事務修改但未提交的數據,如果修改回滾,則事務讀取了無效的數據。 |
不可重覆讀 | 同一個事務中兩次相同查詢中,讀取到不同的數據 | 一個事務兩次查詢期間,另一個併發事務對數據進行了更新。 |
幻讀 | 同一個事務在兩次相同的查詢中,讀取到不同記錄數的數據 | 一個事務兩次查詢期間,另一個併發事務進行了數據新增或刪除。 |
隔離級別
隔離級別 | 說明 | 併發事務可能引起的問題 |
---|---|---|
ISOLATION_DEFAULT | 使用後端資料庫預設的隔離級別 | 具體情況具體分析 |
ISOLATION_READ_UNCOMMITTED | 最低的隔離級別,允許讀取尚未提交的數據變更 | 臟讀、不可重覆讀、幻讀 |
ISOLATION_READ_COMMITTED | 允許讀取併發事務已經提交的數據 | 不可重覆讀、幻讀 |
ISOLATION_REPEATABLE_READ | 對同一欄位的多次讀取結果一致,除非欄位被本事務修改 | 幻讀 |
ISOLATION_SERIALIZABLE | 最高的隔離級別,完全服從ACID原則,通常通過鎖表實現(最慢) | 無 |
3. 事務超時
給定事務一個超時時間,如果特定時間事務沒有執行完畢,事務會自動回滾。
4. 是否只讀?
設置了只讀事務,那麼在此事務執行過程中,其它事務對資料庫的修改對於該事務來說是透明的,即看不到其它事務修改後的數據。這通常用於執行多次查詢來統計信息時,能夠保證數據的整體一致性。
5. 回滾規則
回滾規則定義了哪些異常,事務會進行回滾。預設情況下,事務只有遇到運行時異常才會回滾,而在遇到檢查型異常時不會回滾。
四、Spring事務管理形式
1. 編程式事務
使用TransactionTemplate或PlatformTransactionManager
TransactionTemplate tt = new TransactionTemplate();
tt.execute(status -> {
// 執行操作
doSth();
// 返回操作結果
return obj;
});
2. 聲明式事務
六、總結
- Spring定義了事務管理器的介面,具體實現由特定平臺來實現;
- Spring事務有五個屬性:事務傳播行為、事務隔離級別、事務超時、事務只讀、回滾規則;
- 傳播行為:required、supports、mandatory、required_new、not_support、never、nested;
- 隔離級別:default、read_uncommited、read_committed、repeatable_read、serializable;