Seata 1.5.2 源碼學習( 二 )


劃重點:將來,所有調用 javax.sql.DataSource#getConnection() 都會被攔截,然后在代理對象上執行getConnection(),因此可以這樣說
調 javax.sql.DataSource#getConnection() 實際上執行的是 io.seata.rm.datasource.SeataDataSourceProxy#getConnection()
2. SeataAutoConfiguration
SeataAutoConfiguration里面主要是配置GlobalTransactionScanner(全局事務掃描器)
seata.enabled=true 才會開啟 SeataAutoConfiguration

Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖
GlobalTransactionScanner 也繼承自 AbstractAutoProxyCreator , 同時還實現了InitializingBean接口 。BeanFactory在設置了所有bean屬性之后會調用InitializingBean的afterPropertiesSet()方法
GlobalTransactionScanner#afterPropertiesSet()
Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖
io.seata.common.DefaultValues中定義了很多默認值
Seata 1.5.2 源碼學習

文章插圖
同樣地,因為實現了BeanPostProcessor接口,所以在啟動時BeanFactory實例化Bean之后,會調用GlobalTransactionScanner的postProcessAfterInitialization(),盡管這個postProcessAfterInitialization()方法時從AbstractAutoProxyCreator那里繼承來的,但是不影響啊 , 還是會調用GlobalTransactionScanner這個bean的postProcessAfterInitialization()方法 。于是,最終又會調wrapIfNecessary()方法 。
GlobalTransactionScanner#wrapIfNecessary()
Seata 1.5.2 源碼學習

文章插圖
這里面有一個很重要的邏輯就是,創建了一個GlobalTransactionalInterceptor對象,并賦值給interceptor
AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean()是一個抽象方法,實現在子類GlobalTransactionScanner中
Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖

Seata 1.5.2 源碼學習

文章插圖
因此,所有在GlobalTransactionScanner#wrapIfNecessary()中被代理的對象 , 都被應用GlobalTransactionalInterceptor
GlobalTransactionalInterceptor也是一個MethodInterceptor
也就是說 , 目標方法的調用都會轉到GlobalTransactionalInterceptor#invoke()上
Seata 1.5.2 源碼學習

文章插圖
GlobalTransactionalInterceptor#handleGlobalTransaction()
Seata 1.5.2 源碼學習

文章插圖
事務執行直接調用TransactionalTemplate的execute()方法
io.seata.tm.api.TransactionalTemplate#execute()
Seata 1.5.2 源碼學習

文章插圖
io.seata.tm.api.GlobalTransactionContext#getCurrent() 獲取當前事務
Seata 1.5.2 源碼學習

文章插圖
io.seata.tm.api.TransactionalTemplate#beginTransaction()
Seata 1.5.2 源碼學習

文章插圖
tx是DefaultGlobalTransaction
io.seata.tm.api.DefaultGlobalTransaction#begin()
DefaultGlobalTransaction中的TransactionManager是DefaultTransactionManager
Seata 1.5.2 源碼學習

文章插圖
DefaultTransactionManager中提供了事務相關的底層操作
Seata 1.5.2 源碼學習

文章插圖
io.seata.tm.api.DefaultGlobalTransaction#commit()
Seata 1.5.2 源碼學習

文章插圖
io.seata.tm.api.DefaultGlobalTransaction#rollback()的邏輯與commit()類似,都是重試調用transactionManager.rollback(xid)
全局事務掃描器部分的代碼就看到這里,下面總結一下:
1、配置項seata.enabled=true 會觸發 SeataAutoConfiguration 自動配置
2、SeataAutoConfiguration中創建了一個GlobalTransactionScanner
3、GlobalTransactionScanner繼承了AbstractAutoProxyCreator,并實現InitializingBean接口
4、初始化TM、RM
5、由于繼承了AbstractAutoProxyCreator,所以BeanFactory會調用GlobalTransactionScanner#方法postProcessAfterInitialization(),最終會調用GlobalTransactionScanner#wrapIfNecessary()來為目標對象創建代理對象

推薦閱讀