Seata 1.5.2 源碼學習( 三 )


6、GlobalTransactionScanner#wrapIfNecessary()中創建了一個GlobalTransactionalInterceptor,GlobalTransactionalInterceptor是一個MethodInterceptor
7、在創建代理對象的時候 , 在AbstractAutoProxyCreator#wrapIfNecessary()方法中,為代理對象應用GlobalTransactionalInterceptor,于是所有目標對象上的方法調用就會轉為調用GlobalTransactionalInterceptor#invoke()
8、GlobalTransactionalInterceptor#invoke()方法中,首先獲取被調用的目標對象的Class和Method對象,然后檢查目標方法或類上是否有@GlobalTransactional或@GlobalLock注解,而且配置項中不能禁用全局事務
9、如果加了@GlobalTransactional注解 , 則創建一個AspectTransactional,然后開始處理全局事務,默認傳播特性是REQUIRED
10、如果加了@GlobalLock注解 , 則開始處理全局鎖
11、處理全局事務就是直接調用事務模板中的execute方法,TransactionalTemplate#execute()是一個模板方法,其中定義了事務處理的流程 。首先開啟事務 , 然后執行業務邏輯,最后提交事務 , 異?;貪L事務 。
12、事務操作是在DefaultGlobalTransaction中處理的,最終處理在DefaultTransactionManager 。DefaultTransactionManager負責同步遠程調用,向TC發請求來開啟、提交、回滾事務等操作

Seata 1.5.2 源碼學習

文章插圖
3. 數據庫操作執行SQL語句
通過Java自帶的JDBC操作數據庫通常是這樣的:
Class.forName(driverClass);// 獲取ConnectionConnection connection = DriverManager.getConnection(url,user,password);// 創建Statement或者PreparedStatementStatement stmt = connection.createStatement();stmt.execute(sql);// PreparedStatement ps = connection.prepareStatement(sql);// ps.execute();MyBatis底層也是這一套
接下來看Seata是如何做的
首先是獲取數據庫連接Connection,前面已經說過了,調用DataSource的getConnection()方法底層是在代理對象SeataDataSourceProxy上調用getConnection() 。SeataDataSourceProxy是接口,如果是AT模式 , 則這個數據源代理對象是DataSourceProxy
Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖
DataSourceProxy#getConnection()獲取數據庫連接
Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖
ConnectionProxy#createStatement()
Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖
ConnectionProxy#prepareStatement()
【Seata 1.5.2 源碼學習】
Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖
PreparedStatementProxy 繼承自 StatementProxy,因此下面就直接看PreparedStatementProxy如何執行SQL
PreparedStatementProxy#execute()
Seata 1.5.2 源碼學習

文章插圖
ExecuteTemplate#execute()  是一個模板方法
Seata 1.5.2 源碼學習

文章插圖
挑一個看看吧 , 就挑UpdateExecutor
Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖
UpdateExecutor構造方法中一直調父類的構造法 , 既然如此,那么直接看BaseTransactionalExecutor
Seata 1.5.2 源碼學習

文章插圖
UpdateExecutor#execute()
這個方法時從BaseTransactionalExecutor那里繼承來的 , 又是一個模板方法,可見設計模式是多么重要
Seata 1.5.2 源碼學習

文章插圖
AbstractDMLBaseExecutor#doExecute()
Seata 1.5.2 源碼學習

文章插圖
AbstractDMLBaseExecutor#executeAutoCommitTrue()
Seata 1.5.2 源碼學習

文章插圖

推薦閱讀