千家信息网

怎么用python完成一个分布式事务TCC

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要讲解了"怎么用python完成一个分布式事务TCC",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么用python完成一个分布式事务TCC
千家信息网最后更新 2026年10月31日怎么用python完成一个分布式事务TCC

这篇文章主要讲解了"怎么用python完成一个分布式事务TCC",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么用python完成一个分布式事务TCC"吧!

1、TCC组成

TCC分为3个阶段

  • Try 阶段:尝试执行,完成所有业务检查(一致性), 预留必须业务资源(准隔离性)

  • Confirm 阶段:如果所有分支的Try都成功了,则走到Confirm阶段。Confirm真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源

  • Cancel 阶段:如果所有分支的Try有一个失败了,则走到Cancel阶段。Cancel释放 Try 阶段预留的业务资源。

TCC分布式事务里,有3个角色,与经典的XA分布式事务一样:

  • AP/应用程序,发起全局事务,定义全局事务包含哪些事务分支

  • RM/资源管理器,负责分支事务各项资源的管理

  • TM/事务管理器,负责协调全局事务的正确执行,包括Confirm,Cancel的执行,并处理网络异常

如果我们要进行一个类似于银行跨行转账的业务,转出(TransOut)和转入(TransIn)分别在不同的微服务里,

一个成功完成的TCC事务典型的时序图如下:

2、TCC实践

对于前面的跨行转账操作,最简单的做法是,在Try阶段调整余额,在Cancel阶段反向调整余额,Confirm阶段则空操作。这么做带来的问题是,如果A扣款成功,金额转入B失败,最后回滚,把A的余额调整为初始值。在这个过程中如果A发现自己的余额被扣减了,但是收款方B迟迟没有收到余额,那么会对A造成困扰。

更好的做法是,Try阶段冻结A转账的金额,Confirm进行实际的扣款,Cancel进行资金解冻,这样用户在任何一个阶段,看到的数据都是清晰明了的。

下面我们进行一个TCC事务的具体开发

目前可用于TCC的开源框架,主要为Java语言,其中以seata为代表。我们的例子采用Python语言,使用的分布式事务框架为 https://github.com/yedf/dtm ,它对分布式事务的支持非常优雅。下面来详细讲解TCC的组成

我们首先创建两张表,一张是用户余额表,一张是冻结资金表,建表语句如下:

CREATE TABLE dtm_busi.`user_account` (  `id` int(11) AUTO_INCREMENT PRIMARY KEY,  `user_id` int(11) not NULL UNIQUE ,  `balance` decimal(10,2) NOT NULL DEFAULT '0.00',  `create_time` datetime DEFAULT now(),  `update_time` datetime DEFAULT now());CREATE TABLE dtm_busi.`user_account_trading` (  `id` int(11) AUTO_INCREMENT PRIMARY KEY,  `user_id` int(11) not NULL UNIQUE ,  `trading_balance` decimal(10,2) NOT NULL DEFAULT '0.00',  `create_time` datetime DEFAULT now(),  `update_time` datetime DEFAULT now());

trading表中,trading_balance记录正在交易的金额。

我们先编写核心代码,冻结/解冻资金操作,会检查约束balance+trading_balance >= 0,如果约束不成立,执行失败

def tcc_adjust_trading(cursor, uid, amount):  affected = utils.sqlexec(cursor, "update dtm_busi.user_account_trading set trading_balance=trading_balance + %d where user_id=%d and trading_balance + %d + (select balance from dtm_busi.user_account where id=%d) >= 0" % (amount, uid, amount, uid))  if affected == 0:    raise Exception("update error, maybe balance not enough")

然后是调整余额

def tcc_adjust_balance(cursor, uid, amount):  utils.sqlexec(cursor, "update dtm_busi.user_account_trading set trading_balance = trading_balance+ %d where user_id=%d" %( -amount, uid))  utils.sqlexec(cursor, "update dtm_busi.user_account set balance=balance+%d where user_id=%d" %(amount, uid))

下面我们来编写具体的Try/Confirm/Cancel的处理函数

@app.post("/api/TransOutTry")def trans_out_try():  # 事务以及异常处理  tcc_adjust_trading(c, out_uid, -30)  return {"dtm_result": "SUCCESS"}@app.post("/api/TransOutConfirm")def trans_out_confirm():  # 事务以及异常处理  tcc_adjust_balance(c, out_uid, -30)  return {"dtm_result": "SUCCESS"}@app.post("/api/TransOutCancel")def trans_out_cancel():  # 事务以及异常处理  tcc_adjust_trading(c, out_uid, 30)  return {"dtm_result": "SUCCESS"}@app.post("/api/TransInTry")def trans_in_try():  # 事务以及异常处理  tcc_adjust_trading(c, in_uid, 30)  return {"dtm_result": "SUCCESS"}@app.post("/api/TransInConfirm")def trans_in_confirm():  # 事务以及异常处理  tcc_adjust_balance(c, in_uid, 30)  return {"dtm_result": "SUCCESS"}@app.post("/api/TransInCancel")def trans_in_cancel():  # 事务以及异常处理  tcc_adjust_trading(c, in_uid, -30)  return {"dtm_result": "SUCCESS"}

到此各个子事务的处理函数已经OK了,然后是开启TCC事务,进行分支调用

@app.get("/api/fireTcc")def fire_tcc():    # 发起tcc事务    gid = tcc.tcc_global_transaction(dtm, utils.gen_gid(dtm), tcc_trans)    return {"gid": gid}# tcc事务的具体处理def tcc_trans(t):    req = {"amount": 30} # 业务请求的负荷    # 调用转出服务的Try|Confirm|Cancel    t.call_branch(req, svc + "/TransOutTry", svc + "/TransOutConfirm", svc + "/TransOutCancel")    # 调用转入服务的Try|Confirm|Cancel    t.call_branch(req, svc + "/TransInTry", svc + "/TransInConfirm", svc + "/TransInCancel")

至此,一个完整的TCC分布式事务编写完成。

如果您想要完整运行一个成功的示例,那么按照dtmcli-py-sample项目的说明tcc的例子即可

3、TCC的回滚

假如银行将金额准备转入用户2时,发现用户2的账户异常,返回失败,会怎么样?我们修改代码,模拟这种情况:

@app.post("/api/TransInTry")def trans_in_try():  # 事务以及异常处理  tcc_adjust_trading(c, in_uid, 30)  return {"dtm_result": "FAILURE"}

这是事务失败交互的时序图:

这个跟成功的TCC差别就在于,当某个子事务返回失败后,后续就回滚全局事务,调用各个子事务的Cancel操作,保证全局事务全部回滚。

4、TCC网络异常

TCC在整个全局事务的过程中,可能发生各类网络异常情况,典型的是空回滚、幂等、悬挂,由于TCC的异常情况,和SAGA、可靠消息等事务模式有相近的地方,因此我们把所有异常的解决方案统统放在这篇文章 分布式事务最经典的七种解决方案 的异常处理章节进行讲解

感谢各位的阅读,以上就是"怎么用python完成一个分布式事务TCC"的内容了,经过本文的学习后,相信大家对怎么用python完成一个分布式事务TCC这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

事务 阶段 处理 分布式 业务 余额 全局 成功 分支 资源 情况 用户 金额 调整 个子 网络 资金 学习 服务 检查 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 河南云网互联网络科技有限公司 互联网科技巨头监管 互联网巨头科技公司 广州互联网科技公司 顺玮阁互联网科技 郑州华宇互联网科技 互联网科技网站 互联网科技大会 互联网之后的科技是什么 新华互联网科技2019 深圳育鹏互联网科技有限公司招聘 互联网科技研发水平 上海京穆互联网科技有限公司 锡山区互联网智能科技产品供应 山东星卡互联网科技有限公司官网 产业互联网科技服务公司 浙南科技城互联网大厦招聘 互联网安防科技感 宁波跨境商互联网科技有限公司 科技互联网专业务虚会材料 互联网科技名片 互联网科技公司的优势 互联网科技有限公司经营范围 科技企业和互联网企业 互联网科技公司的市场部门 剑昆互联网络科技有限公司临桂 深圳市优智互联网科技有限公司 互联网科技和法律行业 中科明德北京互联网科技 富国互联网科技002692
0