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


    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
    @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 请求会被编码成

    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 请求:

    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,才会以文本协议发送。例如:

    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 的运行状态:

    $ 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

  • 相关阅读:
    idea连接远程主机
    图像分割:DeepLabV2网络简介
    【吴恩达机器学习笔记】十二、降维
    MockingBird,手把手教你克隆您的声音,AI代言人,惊艳你的耳朵!
    day46 完全背包理论基础 518. 零钱兑换 II 377. 组合总和 Ⅳ
    【Bluetooth|蓝牙开发】一、开篇词 | 打造全网最详细的Bluetooth开发教程
    Kafka 杂谈
    Serverless 时代下微服务应用全托管解决方案
    JSD-2204-Knife4j框架-处理响应结果-Day07
    分享一个高颜值开源计算器
  • 原文地址:https://www.cnblogs.com/DKSL/p/16358143.html