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

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 解決分布式事務問題