作者 | 刘晓敏  GitHub ID:dk-lockdown
来源 | 阿里巴巴云原生公众号

背景

2020 年 4 月,我们开始尝试实现 go 语言的分布式事务框架 Seata-Golang。众所周知,Seata AT 模式以无业务代码侵入的特点,被广大开发者推崇。Java 版 Seata AT 模式通过对 DataSource 数据源进行代理,在 sql 语句执行时,对 sql 拦截解析,获取数据库对应数据在 sql 语句执行前后的副本,序列化后保存起来,在 TC 协调回滚时用来回滚对应数据。实现 go 版本 client 的 AT 模式时,怎样对业务开发者更友好,入侵更少,成了首要考虑的目标。

使用 go 操作数据库时,我们会使用到 go 语言的官方库 database/sql,通过 sql.Open("mysql", ${dsn}) 获取一个数据源操作对象 db。开启事务时,使用 db.Begin()db.BeginTx(ctx, &sql.TxOptions{}) 获得事务操作对象 tx,执行 sql 查询使用 tx.Query;执行 sql 新增、修改、删除,使用 tx.Exec;最后使用 tx.Commit() 提交或使用 tx.Rollback() 回滚。

go 语言官方库 database/sql 提供了一个标准抽象层,通过实现不同的 driver 一套标准的抽象 API 可以操作不同的数据库。开发 Go 版本的 AT 模式,必然要兼容 database/sql。通过研究 database/sql 的 api,创建数据源操作对象,数据库有关的配置必须通过 Data Source Name (DSN) 抽象传递进去,下面是 DSN 的定义:

[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]

实现 AT 模式对数据源代理是需要和事务协调器 TC 进行交互的,如果将 AT 模式实现在 driver 层,那么和 TC 交互的一些参数必须要通过 DSN 传递到 driver,这样有些破坏它的设计。所以,最后采取了一种折中方案,在 database/sql 层之上实现 AT 模式,代理 database/sql 创建出来的数据源操作对象。数据源代理对象实现 database/sql 库定义的 Tx 接口,另外再提供一个开启事务的方法:Begin(),虽然没有完全兼容 database/sql 的 api,但是关键接口和它的定义成一样,勉强还能接受。到此,Seata-Golang 项目核心功能的开发已完成。

type Tx interface {Commit() errorRollback() error
}

转折

Seata-Golang  开源后,逐渐被一些开发者了解和接触,社区也对 Seata-Golang 发出了一些反馈的声音,不少开发者并不习惯写原生 sql,他们希望将 Seata-Golang 集成到 ORM 框架,因为当时的设计没有完全兼容 database/sql 导致集成上遇到一些困难。随着社区的热切呼唤,且得益于前期对 driver 的一些研究,念念不忘必有回响,今年 3 月突然灵感迸发:为什么参数一定要通过 DSN 传递?Seata-Golang Client 初始化后,在需要时通过 Client 端的 API config.GetATConfig() 直接获取使用不就可以了。

于是工作之余,历时 2 周开发,第一个集成 Seata-Golang 的完全兼容 database/sql 的 mysql driver 被开发出来,项目开源在 https://github.com/opentrx/mysql,现处于 beta 状态,希望社区开发者使用后能有一些反馈,可通过例子:https://github.com/opentrx/seata-go-samples,查看使用方式并进行测试。

driver 的一些细节

  • 使用该 driver 进行分布式事务操作时,不能在 dsn 中设置 interpolateParams 参数为 true

这涉及到 mysql 的两个协议:Text 协议和 Binary 协议。有关两个协议的区别,可以在文末参考文档找到资料。实现该 driver 只对 binary 协议进行了处理,开启 interpolateParams 会使用 text 协议执行 sql。

  • 使用该 driver 在需要加入全局事务组和 tc 进行交互时,需要使用 db.BeginTx(ctx context.Context, opts driver.TxOptions) 方法,并在 ctx 中加入 XID 全局事务 id 的值
ctx := context.WithValue(context.Background(), mysql.XID, c.Request.Header.Get("XID"))
tx, err := dao.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelDefault,ReadOnly:  false,})

XID 传递到 driver 层,会保存在 &mysqlConn 连接对象中,在和 TC 交互时用到。

  • 使用该 driver 的分布式事务功能前需要先初始化 seata-golang client 和 mysql driver
  config.InitConf(configPath)client.NewRpcClient()mysql.InitDataResourceManager()mysql.RegisterResource(config.GetATConfig().DSN)

具体可参考 seata-go-samples。

寄语

此项目开源到今年 4 月即满一年,通过本文中的 mysql driver,希望能降低使用门槛,让大家真正用起来,大家在选择微服务开发技术栈时也不用担心 go 语言没有分布式事务处理方案。另外,此项目还很年轻,仍有许多需要完善的地方,希望感兴趣的朋友一起参与到社区来对它进行完善!希望听到社区更多用户的反馈!
如果你有任何疑问,欢迎钉钉扫码加入交流群【钉钉群号 33069364】:

作者简介

刘晓敏 (GitHubID dk-lockdown),目前就职于 h3c 成都分公司,擅长使用 Java/Go 语言,在云原生和微服务相关技术方向均有涉猎,目前专攻分布式事务。

参考资料

  • seata 官方

  • java 版 seata

  • seata-golang 项目地址

  • driver 地址

  • seata-golang go 夜读 b站分享

  • 基于 getty 的 seata-golang 通信模型详解

  • seata-golang 接入指南

  • mysql protocol

Go Mysql Driver 集成 Seata-Golang 解决分布式事务问题相关推荐

  1. 解决分布式事务,Seata真香

    目录 背景介绍 什么是分布式事务 什么叫做逆向补偿呢 互联网最流行的分布式事务组件seata 总结 背景 大家好,今天给大家分享一个在 2022 年出去面试 Java 几乎必问的一个技术,那就是 se ...

  2. 安装mysql驱动报错_java.sql.SQLException: org.gjt.mm.mysql.Driver 报错【解决办法】

    今天爱分享给大家带来java.sql.SQLException: org.gjt.mm.mysql.Driver 报错[解决办法],希望能够帮助到大家. spring boot mysql 中启动报错 ...

  3. druid seata 配置_分布式事务解决方案——Seata使用

    在微服务开发过程中分布式事务一直是一个比较重要的问题,之前对于分布式事务的解决方法一般会通过MQ的最终一致性来解决,尤其是RocketMQ的事务消息,感兴趣的可以看Spring Boot整合Rocke ...

  4. MySQL中基于XA实现的分布式事务

    文章目录 一.前言 二.XA基础 2.1 XA基础知识 2.1.1 DTP是什么? 2.1.2 DTP的结构:AP TM RM(重点001) 2.1.3 DTP的重要概念 2.2 XA事务:基于两阶段 ...

  5. Spring Cloud Alibaba 高级特性 分布式事务:Alibaba Seata 如何实现分布式事务

    本讲咱们要解决分布式事务这一技术难题,这一讲咱们将介绍三方面内容: 讲解分布式事务的解决方案: 介绍 Alibaba Seata 分布式事务中间件: 分析 Seata 的 AT 模式实现原理. 分布式 ...

  6. SpringBoot+Nacos+Seata实现Dubbo分布式事务管理

    SpringBoot+Nacos+Seata实现Dubbo分布式事务管理 https://www.shangmayuan.com/a/a3ba056126ba45db9b8dfd5b.html 源码下 ...

  7. SpringBoot+Zookeeper+Seata实现Dubbo分布式事务管理

    面我已经写过一篇SpringBoot+Nacos+Seata实现Dubbo分布式事务管理的文章,今天为什么还要写这篇呢,是因为好多公司还在用Zookeeper作为Dubbo的注册中心和配置中心在大规模 ...

  8. 基于消息中间件解决分布式事务的开源框架Myth

    基于消息中间件的解决分布式事务框架:https://github.com/yu199195/myth 1.rpc框架支持 : dubbo,motan,springcloud. 2.消息中间件支持 : ...

  9. 老板,明年我用Seata搞定分布式事务管理的规范化建设 | 中篇

    辞旧迎新,22年要结束了,明年做什么想好了嘛?要不要用 Seata 搞定公司分布式事务管理的规范化建设? 欢迎关注微信公众号「架构染色」交流和学习 一.背景 在上一篇<明年用Seata搞定分布式 ...

  10. rabbitmq 查询版本_基于rabbitmq解决分布式事务

    分布式事务要解决的问题是保证二个数据库数据的一致性,本地事务ACID属于刚性事务,基于CAP理论,分布式事务的核心要点柔性事务,最终一致性. 基于rabbitmq解决分布式事务要点如下 生产者采用发送 ...

最新文章

  1. 使用 FOR XML PATH 合并SQL Server查询结果的重复行
  2. 2017-2018-2 『网络对抗技术』Exp1:PC平台逆向破解 20165335
  3. python document_python 处理document文档 保留原样式
  4. Java命令学习系列(三)——Jmap
  5. 【算法训练】Leetcode 1295. 统计位数为偶数的数字(2020.06.09 )
  6. [转]调试 smallcorgi/Faster-RCNN_TF 的demo过程遇到的问题
  7. AtCoder Beginner Contest 081
  8. 06-移动端开发教程-fullpage框架
  9. C++原子性实现无锁队列
  10. 5. CSS 类选择器
  11. 业务方如何理解产品,更顺利地推进产品需求?
  12. python配置geany教程视频_Python使用geany工具配置方法
  13. 机器学习——神经网络实验(附全过程代码)
  14. python数据分析学习day05:随机函数和常用函数
  15. 多伦多大学好吗_大家对多伦多大学有什么评价?
  16. Knowledge 3命题逻辑形式推演(resolution归结原理- -- 1条规则)
  17. 下载必应搜索背景图并设置为背景
  18. 等保-机房来访人员进出登记表
  19. 人脸图像GAN,今如何?(附多篇论文下载)
  20. python简单实现注意力机制

热门文章

  1. 【安全漏洞】ThinkPHP 3.2.3 漏洞复现
  2. ctf图片隐写之修改图片高度
  3. 设计模式C++实现(11)——装饰模式
  4. 设计模式C++实现(6)——建造者模式
  5. addr 与 offset 区别
  6. 16、IN和NOT IN用法详解
  7. 15、MySQL运算符的优先级
  8. 单源最短路径-Dijkstra(迪杰斯特拉算法)
  9. 【PAT乙级】1064 朋友数 (20 分)
  10. android服务的说法错误的是,下面关于Android开发描述有误的一项是()。