前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >dotnet core 也能协调分布式事务啦!

dotnet core 也能协调分布式事务啦!

原创
作者头像
用户2627641
发布2022-07-02 13:38:09
3630
发布2022-07-02 13:38:09
举报
文章被收录于专栏:dbmesh

2022 年 5 月 24 日,我们发布了 DBPack v0.1.0 版本,该版本主要 release 了分布式事务功能。在我们的规划里,DBPack 是要支持所有微服务开发语言协调分布式事务的,但经过社区反馈,dotnet core 并不支持。于是,我们在 v0.1.1 对 dotnet core 进行了支持。下面就如何支持 dotnet core 做一个说明。

MySql 协议

先请允许我对 MySql 的通信协议做一个简单的介绍。MySql 支持两种协议,一种是文本(Text)协议,一种是二进制(Binary)协议。MySql 客户端使用 COM_QUERY 发出的请求,MySql 服务端会以文本协议响应结果;使用 COM_STMT_EXECUTE 命令发出的请求,会以二进制协议响应结果。

在我们用程序调用 MySql Client SDK 发起请求的时候,不同的 MySql Client SDK 会默认使用不同的协议发送请求,但大部分 MySql Client SDK 都支持文本协议和二进制协议,我们可以通过修改属性配置改变 MySql Client SDK 的默认行为。比如:

  • JAVA
代码语言:javascript
复制
@Mapper
public interface ProductMapper {
    @Update("UPDATE /*+ XID('${xid}') */ `product`.`inventory` SET `available_qty` = `available_qty` - #{qty}, allocated_qty = allocated_qty + #{qty} WHERE product_sysno = #{productSysNo} AND available_qty >= #{qty}")
    boolean allocateInventory(@Param("xid") String xid, @Param("productSysNo") long productSysNo, @Param("qty") int qty);
}

在 java 语言编写的微服务中,我们写了一个方法去修改商品的库存,当我们传入参数提交执行的时候,默认该 SQL 请求会被编码成

代码语言:javascript
复制
update /*+ XID('gs/aggregationSvc/81336085455405058') */ product.inventory set available_qty = available_qty - 2, allocated_qty = allocated_qty + 2 where product_sysno = 1 and available_qty >= 2;

通过 COM_QUERY 命令发出。

我们可以通过修改连接字符串,在原来的 jdbc:mysql://dbpack2:13307/product 上加上 useServerPrepStmts=true,改为 jdbc:mysql://dbpack2:13307/product?useServerPrepStmts=true,再次执行时,会首先发出 COM_STMT_PREPARE 请求:

代码语言:javascript
复制
UPDATE /*+ XID('gs/aggregationSvc/2612341069705662465') */ product.inventory set available_qty = available_qty - ?, allocated_qty = allocated_qty + ? WHERE product_sysno = ? and available_qty >= ?

获取到 statement id 后,再将 statement id 和请求参数编码后通过 COM_STMT_EXECUTE 命令发出。

  • Golang

Golang MySql driver 默认是以二进制协议发送带参数的 DML 请求的,通过在 dsn 上加上参数 interpolateParams=true,才会以文本协议发送。例如:

代码语言:javascript
复制
dksl:123456@tcp(127.0.0.1:13306)/employees?interpolateParams=true&timeout=10s&readTimeout=10s&writeTimeout=10s&parseTime=true&loc=Local&charset=utf8mb4,utf8

Dotnet Core

Dotnet core 如果使用 EntityFrameworkCore 或者 Dapper 来访问数据库,目前还不支持使用 Prepared Statement,下面这两个 issue 有相关说明:

https://github.com/dotnet/efcore/issues/5459

https://github.com/DapperLib/Dapper/issues/474

在 v0.1.0 版本,我们只对 COM_STMT_EXECUTE 请求做了拦截处理,来协调分布式事务问题。dotnet core 使用 COM_QUERY 提交请求自然无法协调分布式事务,在 v0.1.1 我们增加了 COM_QUERY 请求协调分布式事务的支持,这样真正做到了支持所有微服务语言协调分布式事务。

dotnet core sample 见:https://github.com/CECTC/dbpack-samples/tree/main/dotnet。

其他特性

本次发版,还修复了一些 bug,增加了 status api 用于查询 dbpack 的运行状态:

代码语言:javascript
复制
$ curl http://localhost:9999/status
$ {
	"listeners": [{
		"protocol_type": "mysql",
		"socket_address": {
			"address": "0.0.0.0",
			"port": 13306
		},
		"active": true
	}],
	"distributed_transaction_enabled": true,
	"is_master": true
}

至此,我们有了

  • /live
  • /ready
  • /status
  • /metrics

这些 api 辅助我们查看 dbpack 的运行状态。

完整的版本变更日志请看 https://github.com/CECTC/dbpack/releases。

在下一个版本,我们会增加 tracing 和审计日志的功能。

一些链接

DBPack 项目地址:https://github.com/cectc/dbpack

DBPack 文档:https://cectc.github.io/dbpack-doc/#/

DBPack-samples:https://github.com/cectc/dbpack-samples

DBPack 介绍:https://mp.weixin.qq.com/s/DmXfk5bAcVYdnOwvp8ocHA

事件驱动的分布式事务架构设计:https://mp.weixin.qq.com/s/r43JvRY3LCETMoZjrdNxXA

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MySql 协议
  • Dotnet Core
  • 其他特性
  • 一些链接
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档