4

带你用go轻松完成一个saga分布式事务

 2 years ago
source link: https://studygolang.com/articles/35154
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

带你用go轻松完成一个saga分布式事务

yedf · 5天之前 · 196 次点击 · 预计阅读时间 1 分钟 · 大约8小时之前 开始浏览    

我们团队在引入go语言做微服务的过程中,遇见了分布式事务的强需求。我们的交易中心涉及大量的业务,包括了商品、库存、各类营销活动、商品权限等等,按照我们微服务的设计,需要拆分到多个微服务。原先由本地事务保证的ACID,现在需要分布式事务方案来保证交易的正确性。

我们调研了大量开源项目,发现只有java提供了分布式事务的中间件,其他语言,暂未发现成熟的方案。这种背景下,我们内部开发了针对go语言分布式事务的DTM项目,线上稳定之后,我们将它开源出来,github地址为:yedf/dtm

虽然DTM最初针对我们的go语言微服务,但是我们的设计方案,充分考虑了跨语言特性,将底层通信设计成HTTP(未来会支持grpc),并且将客户端做的非常轻,代码量非常少。

下面我们来看一个Go语言接入DTM的简单例子:

const DtmServer = "http://localhost:8080/api/dtmsvr"
const startBusi = "http://localhost:8081/api/busi_saga"
req := &gin.H{"amount": 30} // 微服务的负荷
// 生成dtm的saga对象
saga := dtm.SagaNew(DtmServer).
  // 添加两个子事务
  Add(startBusi+"/TransOut", startBusi+"/TransOutCompensate", req).
  Add(startBusi+"/TransIn", startBusi+"/TransInCompensate", req)
  // 提交saga事务
err := saga.Commit()

上述提交到dtm的saga事务,包括了两个子事务,TransOut和TransIn,以及两个子事务对应的补偿事务。事务提交到DTM后,DTM保证TransOut TransIn要么全部执行成功,要么任何一个子事务失败,会将执行过的子事务,再执行相应的补偿事务。

如果TransOut、TransIn都执行成功,时序图如下:

image.png

如果TransOut成功、而TransIn失败,时序图如下:

image.png

如果您需要进一步了解上述例子,可以移步yedf/dtm


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK