golang如何使用DTM分布式事务框架_golang DTM分布式事务框架使用方法

张开发
2026/4/16 20:48:15 15 分钟阅读

分享文章

golang如何使用DTM分布式事务框架_golang DTM分布式事务框架使用方法
DTM Saga 的 Do/Undo 接口必须拆分为两个独立 HTTP 路径因 DTM 仅通过 URL 路径识别子事务语义复用路径或 query 参数会导致路由错误、补偿失败Undo 需支持空回滚URL 必须为绝对地址gid 需用 uuid接口返回必须含 result 字段TransOut 与 TransIn 应分属不同服务边界Do/Undo 均需幂等且不可依赖前序状态。DTM Saga 的 Do/Undo 接口必须拆成两个独立 HTTP 路径DTM 不识别“一个 handler 里用 query 参数区分 Do/Undo”的写法它靠 URL 路径唯一标识子事务语义。把 /trans/do 和 /trans/undo 写在同一个 http.HandleFunc 里DTM 重试或补偿时会路由错、调错逻辑甚至跳过补偿。正确做法用不同路径注册两个 handler例如 /v1/order/createDo和 /v1/order/create_compensateUndo别用 if r.URL.Query().Get(op) undo 分支——DTM 不传这种参数它只发 POST 到你声明的 Compensate 地址即使单体部署也要确保两个路径能被 DTM 独立发现和调用用 http.ServeMux 分路由没问题但别复用函数名Undo 接口必须容忍“空回滚”比如 Do 根本没执行成功Undo 也得返回 {result: success}否则 DTM 卡在 abort 状态dtmcli.Saga 初始化时 URL 必须是绝对地址DTM client 完全不拼接 URLAction 和 Compensate 字段填相对路径如 /api/trans/out会导致请求发到 localhost:8080而不是你的业务服务。这是新手最常踩的坑错误现象是 DTM 日志显示 “HTTP 404” 或 “connection refused”但你的服务明明在跑。必须写成带协议和 host 的完整地址http://order-svc:8080/v1/order/createhost 不能写 localhost本地调试除外要填服务发现能解析的名比如 order-svc 或 Kubernetes Service 名gid 务必用 uuid.NewString() 生成别用时间戳或自增 ID——DTM 靠它做幂等去重重复 gid 会导致事务被静默丢弃所有接口返回体必须含 result 字段且为字符串{result: success} 或 {result: failure}DTM 只认这个字段判断成败TransOut 和 TransIn 不能塞进同一个 Go HTTP server 实例不是技术限制而是 DTM 的事务建模要求每个子事务必须有明确的服务边界。如果你把转账出账和入账都放在 http://localhost:8080 下DTM 记录的子事务 ID 就会丢失服务粒度Undo 时无法区分该调哪个逻辑分支极易误补偿或漏补偿。本质是服务发现问题——DTM 把 http://trans-out-svc:8080/do 和 http://trans-in-svc:8080/do 当作两个独立服务URL 前缀参与日志追踪和重试上下文硬要单体部署至少用不同端口如 :8081 和 :8082 反向代理Nginx / Traefik暴露两个域名让 DTM 看起来是两个服务哪怕共用一个进程也要用两个独立 http.ServeMux 实例分别监听不同端口避免路由冲突和状态混淆别在 Do 接口里直接 db.Commit()——Saga 是“先预留再确认”真正落库要等 DTM 发来全局提交指令提前 commit 会破坏协调逻辑导致数据不一致Do 接口必须幂等且不能依赖前序步骤成功DTM 会重试失败的 Do 步骤但不会保证执行顺序——比如 TransOut 成功后 TransIn 失败DTM 会重试 TransIn此时 Do 接口若假设“出账一定已发生”就可能重复扣款。Saga 的每个 Do 必须能独立成立、可重复执行。 Vozo Vozo是一款强大的AI视频编辑工具可以帮助用户轻松重写、配音和编辑视频。

更多文章