网站销售好做吗,免费舆情网站下载,今天上海出什么大事了,上海营业执照查询系统简介#xff1a; 2020 年 4 月#xff0c;我们开始尝试实现 go 语言的分布式事务框架 Seata-Golang。众所周知#xff0c;Seata AT 模式以无业务代码侵入的特点#xff0c;被广大开发者推崇。Java 版 Seata AT 模式通过对 DataSource 数据源进行代理#xff0c;在 sql 语句…简介 2020 年 4 月我们开始尝试实现 go 语言的分布式事务框架 Seata-Golang。众所周知Seata AT 模式以无业务代码侵入的特点被广大开发者推崇。Java 版 Seata AT 模式通过对 DataSource 数据源进行代理在 sql 语句执行时对 sql 拦截解析获取数据库对应数据在 sql 语句执行前后的副本序列化后保存起来在 TC 协调回滚时用来回滚对应数据。实现 go 版本 client 的 AT 模式时怎样对业务开发者更友好入侵更少成了首要考虑的目标。 作者 | 刘晓敏 GitHub IDdk-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[?param1value1...paramNvalueN]
实现 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 driverconfig.InitConf(configPath)client.NewRpcClient()mysql.InitDataResourceManager()mysql.RegisterResource(config.GetATConfig().DSN)
具体可参考 seata-go-samples。
寄语
此项目开源到今年 4 月即满一年通过本文中的 mysql driver希望能降低使用门槛让大家真正用起来大家在选择微服务开发技术栈时也不用担心 go 语言没有分布式事务处理方案。
原文链接
本文为阿里云原创内容未经允许不得转载。