Seata 客戶端需要同時啓動 TM 和 RM 嗎?

在分析啓動部分源碼時,我發現 GlobalTransactionScanner 會同時啓動 RM 和 TM client,但根據 Seata 的設計來看,TM 負責全局事務的操作,如果一個服務中不需要開啓全局事務,此時是不需要啓動 TM client的,也就是說項目中如果沒有全局事務註解,此時是不是就不需要初始化 TM client 了,因爲不是每個微服務,都需要 GlobalTransactional,它此時僅僅作爲一個 RM client 而已。

於是我着手將 GlobalTransactionScanner 稍微更改了初始化的規則,由於之前 GlobalTransactionScanner 調用 初始化方法是在 InitializingBean 中的 afterPropertiesSet() 方法中進行,afterPropertySet() 僅僅是當前 bean 初始化後被調用,此時無法得知當前 Spring 容器是否有全局事務註解。

因此我去掉了 InitializingBean,改成了是實現 ApplicationListener,在實例化 bean 的過程中檢查是否有 GlobalTransactional 註解的存在,最後在 Spring 容器初始化完成之後再調用 RM 和 TM client 初始化方法,這時候就可以根據項目是否有用到全局事務註解來決定是否啓動 TM client 了。

這裏附上 PR 地址:https://github.com/seata/seata/pull/1936

隨後在 pr 中討論中得知,目前 Seata 的設計是只有在發起方的 TM 纔可以發起 GlobalRollbackRequest,RM 只能發送 BranchReport(false) 上報分支狀態個 TC 服務端,無法直接發送 GlobalRollbackRequest 進行全局回滾操作。具體的交互邏輯如下:

那麼根據上面的設計模型,自然可以按需啓動 TM client 了。

但是 Seata 後面的優化迭代中,還需要考慮的一點是:

當 Provider 服務出現異常時,是否可以直接由 Provider 的 TM client 發起全局回滾?這也就意味着可以縮短分佈式事務的週期時間,儘快釋放全局鎖讓其他數據衝突的事務儘早的獲取到鎖執行。

也就是說在一個全局事務當中,只要有一個 RM client 執行本地事務失敗了,直接當前服務的 TM client 發起全局事務回滾,不必要等待發起方的 TM 發起的決議回滾通知了。如果要實現這個優化,那麼就需要每個服務都需要同時啓動 TM client 和 RM client。

更多精彩文章請關注作者維護的公衆號「後端進階」,這是一個專注後端相關技術的公衆號。
關注公衆號並回復「後端」免費領取後端相關電子書籍。
歡迎分享,轉載請保留出處。

公衆號「後端進階」,專注後端技術分享!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章