作者 | 劉曉敏
來源 | 阿里巴巴雲原生公眾號
Seata 是一款簡單易用,高性能、開源的一站式分布式事務解決方案。Seata 從2019 年 1 月開源后就受到了大家的追捧,目前已經有幾百家企業在生產環境進行了技術的落地。
2020 年 4 月,我們開始基於 Seata 着手做多語言 golang 項目,經過一年時間的開發,很高興 seata-golang 發布了 1.0.0 版本。
今年 4 月 17 號,有幸在成都 gopher meetup 上將 seata-golang 介紹給熱衷於 golang 的 gopher。


會上我們向大家演示了如何利用 seata-golang 來接入到微服務中保證服務間的數據一致性,另外還向大家介紹了 Seata 的核心原理、MySQL driver 原理和接入、seata-golang 的未來規划,最后就大家關注的 Seata 相關的問題做了 QA。

Seata 原理
活動上,我們結合 seata-golang 的demo 和大家分享了 seata 的工作原理。如下圖所示,是一個 seata at 模式的簡單工作流程。

- TC(即圖中右半部分):Transaction coordinator,它是一個分布式事務協調器。
- TM:Transaction manager,它是一個事務管理器,負責全局事務的開啟、提交和回滾。
- RM:Resource Manager,它是管理分支事務資源的,它加入全局事務組后,向 TC 報告分支事務的執行狀態。
- XID:TM 開啟全局事務時,會在 TC 創建一個 GlobalSession,GlobalSession 的全局唯一標識即為 XID。
- BranchID:RM 向 TC 注冊分支事務后,在 TC 側生成一個 BranchSession,BranchID 全局唯一標識這個 BranchSession。
當 RM 向 TC 報告分支執行失敗時,TC 會標記這個 BranchSession 的狀態為失敗,然后 TM 發起回滾時,TC 根據 XID 找到所有成功執行的事務分支,通知他們進行回滾。
MySQL Driver
最近研發開源出來的mysql driver 項目,基於 go-sql-driver/mysql 1.5.0 版本開發,天然集成了 seata-golang 的分布式事務能力,完全支持 database/sql 庫這層抽象,由於很多 orm 框架都基於 database/sql 做了封裝,所以對 database/sql 的支持意味着 seata-golang 可以完美無縫地接入各種 orm 框架。

driver 的 mysqlTx 對象執行 Commit 或者 Rollback 時,會根據 mysqlConn 的 connCtx 是否有值來決定是否和 tc 交互,報告分支事務的執行狀態。如果執行 Commit,connCtx 有值則把 sqlUndoItemsBuffer 中的 undoLog 和業務數據一起提交到數據庫,然后報告 tc 事務分支提交的狀態(成功還是失敗),否則執行正常的提交。如果執行 Rollback,connCtx 有值則回滾然后向 tc 報告分支執行失敗,tc 會根據這個狀態回滾整個全局事務,connCtx 沒有值則只需正常回滾。

上圖是 undoLog json 序列化后的結構數據,我們可以看到這條數據修改之前,它的 name 是 “TXC”,修改之后它的 name 是 “GTS”,如果對它進行回滾,則生成一個反向的補償語句:update product set name = 'TXC' since = 2014 where id = 1。如果是 insert 操作,則反向補償操作為 delete,如果是一個 delete 操作則方向補償操作為 insert。
未來規划
社區已經有小伙伴將 mysql driver集成到 gorm,並將 seata-golang 用到生產環境。目前 seata-golang 只支持 mysql,小伙伴們可根據 mysql driver 的思路,實現 pgsql 和 oracle 的 driver 。這也是未來 seata-golang 將要規划做的事情之一。

隨着 go 語言微服務開發的興起,分布式事務問題會越來越受到關注,希望社區的朋友可以更多參與進來完善這個框架,讓它發揮生命力、服務社區、創造價值。
如果你有任何疑問,歡迎釘釘掃碼加入交流群【釘釘群號 33069364】
作者簡介
劉曉敏(GitHubID dk-lockdown),目前就職於 h3c 成都分公司,擅長使用 Java/Go 語言,在雲原生和微服務相關技術方向均有涉獵,目前專攻分布式事務。
參考資料
- seata 官方:https://seata.io
- java 版 seata:https://github.com/seata/seata
- seata-golang 項目地址:https://github.com/opentrx/seata-golang
- driver 地址:https://github.com/opentrx/mysql
- seata-golang go 夜讀 b 站分享:https://www.bilibili.com/video/BV1oz411e72T
- 基於 getty 的 seata-golang 通信模型詳解:http://seata.io/zh-cn/blog/seata-golang-communication-mode.html
- seata-golang 接入指南
- Go Mysql Driver 集成 Seata-Golang 解決分布式事務問題
