深入解析 Spring 事務管理原理及源碼
Spring 事務管理(Transaction Management)是企業級應用開發中至關重要的功能之一,它確保數據操作的 原子性、一致性、隔離性、持久性(ACID)。
本篇博客將從 Spring 事務的基本概念 開始,深入 Spring 事務的實現機制,并對 @Transactional
注解的底層執行流程 進行源碼級解析。
1. 事務的基本概念
在數據庫操作中,事務是一個邏輯操作單元,必須滿足 ACID 四大特性:
特性 | 說明 |
---|---|
原子性(Atomicity) | 事務內的所有操作要么全部成功,要么全部失敗 |
一致性(Consistency) | 事務執行后,數據庫從一個一致性狀態轉換到另一個一致性狀態 |
隔離性(Isolation) | 并發事務相互隔離,防止數據不一致 |
持久性(Durability) | 事務提交后,數據永久保存到數據庫 |
?? 2. Spring 事務的核心組件
Spring 通過 聲明式事務 和 編程式事務 來管理數據庫事務。
2.1 Spring 事務的核心接口
組件 | 作用 |
---|---|
PlatformTransactionManager | 事務管理器接口 |
DataSourceTransactionManager | 適用于 JDBC 的事務管理器 |
JpaTransactionManager | 適用于 JPA(Hibernate)的事務管理器 |
TransactionDefinition | 事務的定義,包括隔離級別、傳播行為等 |
TransactionStatus | 事務的當前狀態 |
3. @Transactional
注解解析
Spring 通過 @Transactional
注解實現 聲明式事務,常見用法如下:
@Service
public class OrderService {@Transactionalpublic void createOrder() {// 事務開始orderDao.insertOrder();paymentDao.processPayment(); // 若失敗,事務回滾// 事務提交}
}
3.1 @Transactional 支持的屬性
屬性 | 說明 |
---|---|
propagation | 事務傳播行為 |
isolation | 事務隔離級別 |
timeout | 事務超時時間 |
readOnly | 是否為只讀事務 |
rollbackFor | 指定哪些異常會觸發回滾 |
4. Spring 事務管理的源碼解析
Spring 事務管理的核心是通過 AOP(面向切面編程) 來實現的,底層依賴于 TransactionInterceptor 和 PlatformTransactionManager 來實現事務的創建、提交、回滾等操作。
4.1 事務的創建與提交流程
1?? @Transactional 代理攔截
Spring 事務使用 AOP 代理 來攔截標注了 @Transactional 注解的方法,并通過 TransactionInterceptor 來處理事務的啟動、提交和回滾。具體如下:
public Object invoke(MethodInvocation invocation) throws Throwable {return transactionInterceptor.invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
2?? 獲取事務管理器并創建事務
事務管理器(如 DataSourceTransactionManager)負責管理事務。在 doBegin() 方法中會啟動一個新的事務:
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {Connection conn = DataSourceUtils.getConnection(dataSource);conn.setAutoCommit(false); // 關閉自動提交,開啟事務
}
3?? 執行業務邏輯
當事務開始后,Spring 會執行業務方法(invocation.proceed())。如果在業務邏輯執行過程中出現異常,則會觸發回滾。
4?? 提交或回滾事務
當方法執行完成后,事務會根據是否拋出異常來決定提交還是回滾:
@Override
protected void doCommit(DefaultTransactionStatus status) {status.getConnectionHolder().getConnection().commit();
}@Override
protected void doRollback(DefaultTransactionStatus status) {status.getConnectionHolder().getConnection().rollback();
}
5. 事務的傳播機制
Spring 事務支持 7 種傳播行為,用于控制當前事務如何傳播到嵌套事務中。以下是最常用的幾種傳播行為及其實際應用:
傳播行為實例
1?? REQUIRED(默認行為
)
如果當前存在事務,則加入事務;如果當前沒有事務,則新建事務。例如:
@Transactional(propagation = Propagation.REQUIRED)
public void method1() {// 當前存在事務,將加入該事務
}
如果 method1() 中調用了一個沒有聲明事務的方法 method2(),method2() 會加入到 method1() 的事務中。
2?? REQUIRES_NEW
當前方法總是會新建一個事務,暫停當前事務。例如:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void method1() {// 新建一個事務,當前事務會被掛起
}
當 method1() 執行時,它會暫停外部事務,并在自身內部創建一個新的事務。
3?? NESTED
在當前事務中創建一個嵌套事務。嵌套事務可以獨立提交或回滾,但會共享外部事務的連接。例如:
@Transactional(propagation = Propagation.NESTED)
public void method1() {// 創建一個嵌套事務
}
嵌套事務在提交時不會影響外部事務,但可以獨立回滾。
組合后的效果
REQUIRED + REQUIRES_NEW:會在外部事務的基礎上創建新的事務,外部事務掛起,內部事務完成后恢復外部事務。
REQUIRED + NESTED:如果外部事務提交,嵌套事務也會提交;若外部事務回滾,嵌套事務也會回滾。
通過以上,應該可以很快了解Spring事務,也能更快的去排查跟定位問題。
如果你還有其他問題或想了解更多,歡迎留言交流! 😊