当前位置: 首页 > news >正文

分布式事务Seata TCC模式篇

介绍

​ 官网: https://seata.apache.org/zh-cn/docs/user/mode/tcc

​ 回顾Seata AT 模式基于 支持本地 ACID 事务关系型数据库,如下:

  • 一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
  • 二阶段 commit 行为:马上成功结束,自动 异步批量清理回滚日志。
  • 二阶段 rollback 行为:通过回滚日志,自动 生成补偿操作,完成数据回滚。(如果已经被其他事务修改,可能回滚失败,需考虑策略)

​ 当前Seata TCC (Try-Confirm-Cancel)模式则不不依赖于底层数据资源的事务支持,如下:

  • 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑,又称为Try阶段,进行资源检查与预留
  • 二阶段 commit 行为:调用 自定义 的 commit 逻辑,又称为Confirm阶段在全局事务提交时执行,仅使用Try预留的资源要求操作必须成功且幂等。
  • 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑,又称为Cancel阶段在全局事务回滚时触发释放Try阶段预留的资源同样需要保证幂等性。

​ 所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。是高性能分布式事务解决方案,适用于核心系统等对性能有很高要求的场景。

​ TCC 完全不依赖底层数据库,能够实现跨数据库、跨应用资源管理。需要业务系统自行实现 Try,Confirm,Cancel 三个操作,对业务系统有着非常大的入侵性,设计相对复杂

TCC模式示例

电商扣库存例子

1、Try阶段(资源预留)

用户下单触发库存服务冻结库存,优惠卷服务锁定优惠卷,积分服务预扣积分

以库存表设计为例,需要设计资源预留字段(冻结库存),在Cancel时精准恢复库存,避免数据错乱

CREATE TABLE product_stock (product_id BIGINT PRIMARY KEY,available_stock INT,  -- 可售库存(实际可卖数量)frozen_stock    INT   -- 冻结库存(TCC预留数量)...
);

进行冻结库存 update product_stock set frozen_stock = frozen_stock + 1, available_stock = available_stock -1 where product_id=123,其他的(锁定优惠券、预扣积分)所有都返回成功,才能进入下一阶段。

2、Confirm阶段(正式提交)

正式提交时进行扣减冻结库存,核销优惠券,正式扣除积分

以库存表为例,此时需要减去冻结库存

/* 仅减少冻结库存(不碰可用库存) */
UPDATE product_stock
SET frozen_stock = frozen_stock - 1 -- 释放冻结额度
WHERE product_id = 123;

3、Cancel阶段(回滚释放)

出现Cancel主要原因是因业务异常或系统故障导致事务无法完成,如try阶段库存服务响应成功,优惠卷服务未响应,则触发回滚

update product_stock set frozen_stock = frozen_stock - 1 , available_stock = available_stock + 1 where product_id=123

原理分析

Seata角色说明

  • TC (Transaction Coordinator):事务协调器,全局事务调度中心(Seata-Server)。
  • TM (Transaction Manager)事务管理器,用于触发开启/提交/回滚全局事务。而事务管理器分 2 阶段协调所有资源管理器,在第一阶段询问所有资源管理器**“准备”(Try)是否成功**,如果所有资源均“准备”成功则在第二阶段执行所有资源的**“提交”(Confirm)操作**,否则在第二阶段执行所有资源的**“回滚”(Cancel)操作**,保证所有资源的最终状态是一致的,要么全部提交要么全部回滚。
  • RM (Resource Manager):资源管理器,分支事务注册与三阶段方法的真正执行。提供“准备”、“提交”和“回滚” 3 个操作的资源对应 Try、Confirm、Cancel 3 个方法均由业务编码实现 。

0、核心流程设计

  • 事务启动:TM通过GlobalTransactionalInterceptor拦截业务方法,向TC注册全局事务生成XID。
  • 分支注册:TCC服务(如扣库存)被调用时,TccActionInterceptor拦截Try方法,向TC注册分支事务并记录资源预留信息。

RM启动时,通过TCCResourceManager向TC注册TCC资源(含Commit/Rollback方法信息),建立ResourceID到RPC上下文的映射

  • 二阶段决策
    • 提交:TM通知TC → TC遍历分支事务 → 异步调用各RM的Confirm方法。
    • 回滚:流程类似,调用Cancel方法,失败重试直至成功。

常见问题解决

0、TCC vs AT模式的核心差异

TCC需业务编码实现三阶段,无全局锁,适合高性能与非事务型数据库;AT依赖数据库快照和全局锁,对代码无侵入

1、空回滚(Cancel未执行Try)如何识别空回滚

Try因网络超时未执行,但全局事务因超时触发回滚Cancel。

可以通过查询事务记录表,若无对应XID的Try记录,则判定为空回滚,直接返回成功

  • 事务记录表记录Try状态(如tcc_status(xid, branch_id, status)
  • Cancel执行时检查记录:无记录则空回滚(直接返回成功)

2、**悬挂(Cancel先于Try执行)**如何解决

Try网络延迟,Cancel执行后Try才到达,导致资源永久锁定。

在Cancel执行时插入回滚记录(状态CANCELLED),Try执行前检查此记录。若存在则放弃Try,避免资源锁定

  • Try执行前检查事务记录表,若存在CANCELLED状态则拒绝执行。
  • 分布式锁确保Try/Cancel互斥(如Redis锁)

3、幂等控制,如何保证

网络重传或补偿机制导致Confirm/Cancel重复调用。

通过事务记录表状态机实现。二阶段执行后更新状态,重复调用时根据状态直接返回

  • 事务记录表增加状态字段(如init/committed/cancelled),二阶段执行后更新状态,重复调用时直接返回
http://www.lryc.cn/news/615652.html

相关文章:

  • Linux网络转发系统框架分析
  • 【密码学】7. 数字签名
  • orcad的操作(1)
  • 【LLM】Openai之gpt-oss模型和GPT5模型
  • 【unitrix数间混合计算】2.9 小数部分特征(t_non_zero_bin_frac.rs)
  • DAY35打卡
  • 【js】判断异步函数的返回值要加await
  • 【机器学习深度学习】模型选型:如何根据现有设备选择合适的训练模型
  • Redis面试题及详细答案100道(01-15) --- 基础认知篇
  • 力扣 30 天 JavaScript 挑战 第二题笔记
  • 服务器硬件电路设计之I2C问答(二):I2C总线的传输速率与上拉电阻有什么关系?
  • 常用信号深度解析(SIGINT、SIGPIPE、SIGALRM、SIGTERM等)
  • Java安全-组件安全
  • 谷歌搜索 sg_ss 逆向分析
  • nginx的安装
  • 智能的本质
  • Linux之shell脚本篇(四)
  • 【工具变量】地市人力资本水平数据集(2003-2023年)
  • 9. 堆和栈有什么区别
  • 健全性测试(Sanity Testing):你软件的快速“体检” ✅(省时避坑,确保核心!)
  • PID学习笔记1
  • 复现论文关于3-RPRU并联机器人运动学建模与参数优化设计
  • QT环境搭建
  • 功能测试中常见的面试题-二
  • 【Python 高频 API 速学 ⑥】
  • 09 【C++ 初阶】C/C++内存管理
  • [激光原理与应用-207]:光学器件 - 光纤种子源激光器常用元器件
  • Linux文件系统基石:透彻理解inode及其核心作用
  • 【高等数学】第八章 向量代数与空间解析几何——第四节 空间直线及其方程
  • 分析报告:基于字节连续匹配技术的KV缓存共享实施可能性及其扩展