目標
為后續分析事務源碼前做一個介紹,有些屬性可能光看這個依然看不懂,當看下篇文章Spring事務源碼分析的時候就知道了。
PlatformTransactionManager
/**
* Spring事務抽象的頂級接口
* 以下所說的具體行為以DataSourceTransactionManager這個實現類為准
*/
public interface PlatformTransactionManager {
/**
* 開啟一個事務, 即從給定的數據源中獲取一個連接,關閉自動提交模式,並且將連接綁定到當前線程
* 並且使用給定的參數設置連接的一些行為(隔離級別, 事務只讀特性)
* 如果指定的隔離級別不需要事務,那么開啟一個空事務,也不會從數據源中獲取連接,綁定連接到線程
* @Param definition 定義了事務的一些特征,如傳播行為,隔離級別等。
*/
TransactionStatus getTransaction(TransactionDefinition definition);
/**
* 提交一個事務
*/
void commit(TransactionStatus status);
/**
* 回滾一個事務
*/
void rollback(TransactionStatus status);
}
TransactionDefinition
此接口主要用來定義事務的一些屬性(傳播行為、隔離級別、事務超時時間、事務只讀),接口中定義了一組get方法來獲取這些屬性,並且定義了7個傳播行為。
- PROPAGATION_REQUIRED:如果當前存在事務,則加入該事務,如果當前不存在事務,則創建一個新的事務。
- PROPAGATION_SUPPORTS:如果當前存在事務,則加入事務,如果當前不存在事務,則以非事務運行。
- PROPAGATION_MANDATORY:強制當前必須存在一個事務,在該事務中運行,否則拋出異常。
- PROPAGATION_REQUIRES_NEW:創建一個新的事務,如果當前存在一個事務,掛起當前事務,這兩個事務不相干。
- PROPAGATION_NOT_SUPPORTED:不支持事務,總是以非事務運行,如果當前存在事務,掛起當前事務,獲取一個新的連接來執行。
- PROPAGATION_NEVER:不支持事務,如果存在事務則拋出異常。
- PROPAGATION_NESTED:嵌套事務,如果當前不存在事務,則行為與PROPAGATION_REQUIRED一致。采用JDBC的保存點(Savepoint)實現。
DefaultTransactionDefinition是一個默認的實現類,傳播行為默認為PROPAGATION_REQUIRED,隔離級別默認采用數據庫設置的隔離級別,只讀默認為false。
TransactionStatus
/**
* 此接口定義事務的狀態,此接口獲取的值會影響commit和rollback的行為。
*/
public interface TransactionStatus extends SavepointManager, Flushable {
/**
* 判斷此事務是不是一個新的事務,因為受傳播行為影響,會參與到一個已經存在的事務
* 那么結果就不是一個新事務。
*/
boolean isNewTransaction();
/**
* 判斷是否有保存點(嵌套事務使用)
*/
boolean hasSavepoint();
/**
* 設置該事務的結果只有回滾這一行為,當設置為true后,即便調用commit方法也會發生回滾。
*/
void setRollbackOnly();
boolean isRollbackOnly();
/**
* 事務是否完成,事務提交或者回滾后,事務就完成了。
*/
boolean isCompleted();
}
DefaultTransactionStatus
public abstract class AbstractTransactionStatus implements TransactionStatus {
/**
* 設置為true,那么事務只會有一種結果那就是回滾
* 設置了此屬性,即使調用commit也會執行回滾
*/
private boolean rollbackOnly = false;
/**
* 事務狀態
*/
private boolean completed = false;
/**
* 保存點, 用於嵌套事務
*/
private Object savepoint;
}
public class DefaultTransactionStatus extends AbstractTransactionStatus {
/**
* 代表一個事務對象
* DataSourceTransactionManager事務管理器使用的是其內部類DataSourceTransactionObject
*/
private final Object transaction;
/**
* 代表是不是一個新事務(空事務或真實存在的事務)
* 注: 值為true時不代表開啟一個真實存在的事務
* 當指定事務傳播行為以非事務方式運行的時候,Spring也會將這個值置為true,但是transaction為null
* 以下幾種情況newTransaction = true
* 1. 開啟一個真實存在的事務,必須是新的,參與外部事務的不算。 (transaction != null)
* 2. 開啟一個空事務,必須是新開的。 (transaction = null)
* 2.1 不存在外部真實事務
* 傳播行為可能的值: PROPAGATION_NOT_SUPPORTED,PROPAGATION_SUPPORTS,PROPAGATION_NEVER
* 2.2 存在外部真實事務
* 傳播行為的值: PROPAGATION_NOT_SUPPORTED(因為會將外部事務掛起,以非事務方式運行)
* ==========================================================================
* 判斷是否存在一個新的真實事務: newTransaction == true && transaction != null
* 判斷存在一個空事務(非事務執行方式): newTransaction == true && transaction != null
* 判斷此事務是否參與到外部事務: newTransaction == false && transaction != null
* 判斷存在一個事務(新的真實事務或者參與外部事務):transaction != null
*/
private final boolean newTransaction;
/**
* 值為true,事務管理器需要為當前線程綁定當前事務的屬性以及TransactionSynchronization回調接口
* 這個值會受到AbstractPlatformTransactionManager類中定義的transactionSynchronization字段 * 影響。
* transactionSynchronization可能的值為AbstractPlatformTransactionManager類定義的
* 三個常量,默認為SYNCHRONIZATION_ALWAYS
* 1. SYNCHRONIZATION_ALWAYS:總是激活事務同步(無論是空事務還是真實事務)
* 2. SYNCHRONIZATION_ON_ACTUAL_TRANSACTION: 只有真實事務才激活事務同步
* 3. SYNCHRONIZATION_NEVER:不激活事務同步
* 這個字段的作用:
* 如果為true,那么會將當前的事務屬性(傳播行為、隔離級別、事務名字、事務只讀性、事務是否存活-用以區分 * 是空事務還是真實的事務)以及TransactionSynchronization回調接口
* ==========================================================================
* 在DataSourceTransactionManager事務管理器中並且transactionSynchronization為默認值時:
* newSynchronization=true的情況
* 1. 外部沒有真實事務時
* 1.1 調用事務接口的getTransaction方法開啟一個事務(無論是空事務還是真實事務)
* 2. 外部存在真實事務
* 2.1 事務傳播行為是PROPAGATION_NOT_SUPPORTED、PROPAGATION_REQUIRES_NEW時。
* 因為這兩個傳播行為會掛起外部事務,而開一個新的事務(對應空事務,真實事務)
*/
private final boolean newSynchronization;
/**
* 事務是否只讀
*/
private final boolean readOnly;
/**
* 僅僅用來調試,打印日志,避免重復調用logger.isDebug()
*/
private final boolean debug;
/**
* 被掛起的資源,是一個SuspendedResourcesHolder對象
*/
private final Object suspendedResources;
}