事務的四大特性
原子性
:事務中的所有操作都是不可分割的原子單位。事務中的所有操作要麼全部執行成功,要麼全部執行失敗。
一致性
:事務執行後,資料庫狀態與其他與其他業務規則保持一致。如轉賬業務,無論事務執行成功與否,參與轉賬的兩個賬號餘額之和應該是不變的。
隔離性
:隔離性是指在併發操作中,不同事務之間應該隔離開來,使每個併發中的事務不會相互干擾。
永續性
:一旦事務提交成功,事務中所有的資料操作都必須被持久化到資料庫中,即使提交事務後,資料庫馬上崩潰,在資料庫重啟時,也必須能保證透過某種機制恢復資料。
事務出現的問題
髒讀
(dirty read):一個事務讀取到另外一個事務中未提交的更新資料,即讀取到了髒資料。
不可重複讀
(unrepeatable read):對同一記錄的兩次讀取不一致,因為另一事務對該記錄做了修改。
幻讀
(phantom read):又稱虛讀,事務在兩次查詢返回的資料中發生了資料的缺少或增加,因為另一事務插入或刪除了一條記錄。
事務四大隔離級別
SERIALIZABLE
(序列化):
不會出現任何問題,因為它是對同一資料的訪問時序列的,非併發訪問!
效能最差!
REPEATABLE READ
(可重複讀):
防止髒讀和不可重複讀,不能處理幻讀問題!
效能較SERIALIZABLE好。
READ COMMITTED
(讀已提交資料):
防止髒讀,沒有處理不可重複讀和幻讀;
效能較前兩種更佳。
READ UNCOMMITTED
(讀未提交資料):
可能出現上述所有的事務併發問題;
效能在四種隔離中最優!
MySQL的預設隔離級別為
REPEATABLE READ
!Oracle的預設隔離級別為
READ COMMITTED
!
事務七種傳播行為
事務傳播行為(propagation behavior)指的就是當一個事務方法被另一個事務方法呼叫時,這個事務方法應該如何進行。 例如:methodA事務方法呼叫methodB事務方法時,methodB是繼續在呼叫者methodA的事務中執行呢,還是為自己開啟一個新事務執行,這就是由methodB的事務傳播行為決定的。
PROPAGATION_REQUIRED
:如果當前沒有事務,就建立一個新事務,如果當前存在事務,就加入該事務,該設定是最常用的設定。
PROPAGATION_SUPPORTS
:支援當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行
PROPAGATION_MANDATORY
:支援當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就丟擲異常。
PROPAGATION_REQUIRES_NEW
:建立新事務,無論當前存不存在事務,都建立新事務。
PROPAGATION_NOT_SUPPORTED
:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER
:以非事務方式執行,如果當前存在事務,則丟擲異常。
PROPAGATION_NESTED
:如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則按 REQUIRED 屬性執行
Spring事務分類
宣告式事務
Spring 的宣告式事務管理是建立在 Spring AOP 機制之上的,其本質是對目標方法前後進行攔截,並在目標方法開始之前建立或者加入一個事務,在執行完目標方法之後根據執行情況提交或者回滾事務。
簡單地說,宣告式事務是程式設計式事務 + AOP 技術包裝,使用註解進行掃包,指定範圍進行事務管理。宣告式事務管理要優於程式設計式事務管理,這正是 Spring 倡導的非侵入式的開發方式。
示例:
@Transactionalpublic void test3() // TODO 業務程式碼 }
程式設計式事務
在 Spring 出現以前,程式設計式事務管理對基於 POJO 的應用來說是唯一選擇。我們需要在程式碼中顯式呼叫 beginTransaction()、commit()、rollback() 等事務管理相關的方法,這就是程式設計式事務管理。
簡單地說,程式設計式事務就是在程式碼中顯式呼叫開啟事務、提交事務、回滾事務的相關方法,因此程式碼侵入性較大。
示例:
@Autowiredprivate PlatformTransactionManager transactionManager;public void test3() { TransactionStatus transactionStatus = this。transactionManager。getTransaction(new DefaultTransactionDefinition()); try { // TODO 業務程式碼 // 提交事務 this。transactionManager。commit(transactionStatus); } catch (Exception e) { // 回滾事務 this。transactionManager。rollback(transactionStatus); }}
Spring 事務的原理是使用 AOP 環繞通知 和 異常通知。
注意:在使用 Spring 事務時不能使用 try-catch 進行異常捕獲,要將異常拋給外層,使其進行異常攔截,觸發事務機制。否則導致事務失效,參考下篇Spring事務失效原因彙總
。
Spring事務三大介面
PlatformTransactionManager
事務管理器
TransactionDefinition
事務定義資訊(事務隔離級別、傳播行為、超時、只讀、回滾規則)
TransactionStatus
事務的一些狀態資訊,如是否一個新的事務、是否已被標記為回滾
1:事務管理器PlatformTransactionManager
真正用來管理事務的介面,包含 事務的提交,回滾等資訊。Spring 為不同的持久層框架 提供了 不同的實現類。然後根據不同的持久層框架 去選擇不同的 平臺事務管理器實現類。如果持久層框架使用jdbc,就選擇實現類
DataSourceTransactionManager。如果持久層使用Hibernate,就選擇實現類HibernateTransactionManager。
public interface PlatformTransactionManager extends TransactionManager { //根據事務定義TransactionDefinition,獲取事務 TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException; //提交事務 void commit(TransactionStatus status) throws TransactionException; // 回滾事務 void rollback(TransactionStatus status) throws TransactionException; }
2:事務定義介面TransactionDefinition
事務的定義包括: 事務的隔離級別,事務的傳播屬性,超時時間設定,是否只讀。
事務的隔離級別是資料庫本身的事務功能,事務的傳播屬性則是spring為我們提供的功能,該介面的實現
DefaultTransactionDefinition,預設的事務定義:
1。事務的傳播屬性為PROPAGATION_REQUIRED,即當前沒有事務的時候,建立一個,如果有則使用當前事務
2。事務的隔離級別採用底層資料庫預設的隔離級別
3。超時時間採用底層資料庫預設的超時時間
4。是否只讀為false
public class DefaultTransactionDefinition implements TransactionDefinition, Serializable { private int propagationBehavior = PROPAGATION_REQUIRED; private int isolationLevel = ISOLATION_DEFAULT; private int timeout = TIMEOUT_DEFAULT; private boolean readOnly = false; //略}
3:事務執行狀態TransactionStatus
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable { /** * 是否有儲存點 */ boolean hasSavepoint(); void flush();}
TransactionStatus它繼承了SavepointManager介面,SavepointManager是對事務中上述儲存點功能的封裝,如下:
public interface SavepointManager { // 建立一個儲存點 Object createSavepoint() throws TransactionException; // 釋放一個儲存點 void releaseSavepoint(Object savepoint) throws TransactionException; // 回滾一個儲存點 void rollbackToSavepoint(Object savepoint) throws TransactionException;}
TransactionStatus本身更多儲存的是事務的一些狀態資訊:
是否是一個新的事物
是否有儲存點
是否已被標記為回滾
事務的五種狀態
1. 活動狀態
事務在執行時的狀態叫活動狀態。
2. 部分提交狀態
事務中最後一條語句被執行後的狀態叫部分提交狀態。
3. 失敗狀態
事務不能正常執行的狀態叫失敗狀態。
4. 提交狀態
事務在部分提交後,將往硬碟上寫入資料,當最後一條資訊寫入後的狀態叫提交狀態。進入提交狀態的事務就成功完成了。
5. 中止狀態
事務回滾並且資料庫已經恢復到事務開始執行前的狀態叫中止狀態。