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

如何在业务中体现TCC事务模型?

在分布式系统设计中,随着微服务的流行,通常一个业务操作被拆分为多个子任务,比如电商系统的下单和支付操作,就涉及到了创建和更新订单、扣减账户余额、扣减库存、发送物流消息等,那么在复杂业务开发中,如何保证最终数据一致性呢?

TCC 事务模型是什么

TCC(Try-Confirm-Cancel)的概念来源于 Pat Helland 发表的一篇名为“Life beyond Distributed Transactions:an Apostate’s Opinion”的论文。

TCC 提出了一种新的事务模型,基于业务层面的事务定义,锁粒度完全由业务自己控制,目的是解决复杂业务中,跨表跨库等大颗粒度资源锁定的问题。TCC 把事务运行过程分成 Try、Confirm / Cancel 两个阶段,每个阶段的逻辑由业务代码控制,避免了长事务,可以获取更高的性能。

TCC 的各个阶段

TCC 的具体流程如下图所示:

1.png

Try 阶段:调用 Try 接口,尝试执行业务,完成所有业务检查,预留业务资源。

Confirm 或 Cancel 阶段:两者是互斥的,只能进入其中一个,并且都满足幂等性,允许失败重试。

  • Confirm 操作:对业务系统做确认提交,确认执行业务操作,不做其他业务检查,只使用 Try 阶段预留的业务资源。
  • Cancel 操作:在业务执行错误,需要回滚的状态下执行业务取消,释放预留资源。

Try 阶段失败可以 Cancel,如果 Confirm 和 Cancel 阶段失败了怎么办?

TCC 中会添加事务日志,如果 Confirm 或者 Cancel 阶段出错,则会进行重试,所以这两个阶段需要支持幂等;如果重试失败,则需要人工介入进行恢复和处理等。

应用 TCC 的优缺点

实际开发中,TCC 的本质是把数据库的二阶段提交上升到微服务来实现,从而避免数据库二阶段中长事务引起的低性能风险。

所以说,TCC 解决了跨服务的业务操作原子性问题,比如下订单减库存,多渠道组合支付等场景,通过 TCC 对业务进行拆解,可以让应用自己定义数据库操作的粒度,可以降低锁冲突,提高系统的业务吞吐量。

TCC 的不足主要体现在对微服务的侵入性强,TCC 需要对业务系统进行改造,业务逻辑的每个分支都需要实现 try、Confirm、Cancel 三个操作,并且 Confirm、Cancel 必须保证幂等。

另外 TCC 的事务管理器要记录事务日志,也会损耗一定的性能。

从真实业务场景分析 TCC

下面以一个电商中的支付业务来演示,用户在支付以后,需要进行更新订单状态、扣减账户余额、增加账户积分和扣减商品操作。

在实际业务中为了防止超卖,有下单减库存和付款减库存的区别,支付除了账户余额,还有各种第三方支付等,这里我们为了描述方便,统一使用扣款减库存,扣款来源是用户账户余额。

image.png

业务逻辑拆解

我们把订单业务拆解为以下几个步骤:

  • 订单更新为支付完成状态
  • 扣减用户账户余额
  • 增加用户账户积分
  • 扣减当前商品的库存

如果不使用事务,上面的几个步骤都可能出现失败,最终会造成大量的数据不一致,比如订单状态更新失败,扣款却成功了;或者扣款失败,库存却扣减了等情况,这个在业务上是不能接受的,会出现大量的客诉。

如果直接应用事务,不使用分布式事务,比如在代码中添加 Spring 的声明式事务 @Transactional 注解,这样做实际上是在事务中嵌套了远程服务调用,一旦服务调用出现超时,事务无法提交,就会导致数据库连接被占用,出现大量的阻塞和失败,会导致服务宕机。另一方面,如果没有定义额外的回滚操作,比如遇到异常,非 DB 的服务调用失败时,则无法正确执行回滚。

业务系统改造

下面应用 TCC 事务,需要对业务代码改造,抽象 Try、Confirm 和 Cancel 阶段。

  • Try 操作

Try 操作一般都是锁定某个资源,设置一个预备的状态,冻结部分数据。比如,订单服务添加一个预备状态,修改为 UPDATING,也就是更新中的意思,冻结当前订单的操作,而不是直接修改为支付成功。

库存服务设置冻结库存,可以扩展字段,也可以额外添加新的库存冻结表。积分服务和库存一样,添加一个预增加积分,比如本次订单积分是 100,添加一个额外的存储表示等待增加的积分,账户余额服务等也是一样的操作。

  • Confirm 操作

Confirm 操作就是把前边的 Try 操作锁定的资源提交,类比数据库事务中的 Commit 操作。在支付的场景中,包括订单状态从准备中更新为支付成功;库存数据扣减冻结库存,积分数据增加预增加积分。

  • Cancel 操作

Cancel 操作执行的是业务上的回滚处理,类比数据库事务中的 Rollback 操作。首先订单服务,撤销预备状态,还原为待支付状态或者已取消状态,库存服务删除冻结库存,添加到可销售库存中,积分服务也是一样,将预增加积分扣减掉。

执行业务操作

下面来分析业务的实际执行操作,首先业务请求过来,开始执行 Try 操作,如果 TCC 分布式事务框架感知到各个服务的 Try 阶段都成功了以后,就会执行各个服务的 Confirm 逻辑。

如果 Try 阶段有操作不能正确执行,比如订单失效、库存不足等,就会执行 Cancel 的逻辑,取消事务提交。

TCC 对比 2PC 两阶段提交

TCC 事务模型的思想类似 2PC 提交,下面对比 TCC 和基于 2PC 事务 XA 规范对比。

对比 2PC 提交

image (1).png

  • 第一阶段

在 XA 事务中,各个 RM 准备提交各自的事务分支,事实上就是准备提交资源的更新操作(insert、delete、update 等);而在 TCC 中,是主业务操作请求各个子业务服务预留资源。

  • 第二阶段

XA 事务根据第一阶段每个 RM 是否都 prepare 成功,判断是要提交还是回滚。如果都 prepare 成功,那么就 commit 每个事务分支,反之则 rollback 每个事务分支。

在 TCC 中,如果在第一阶段所有业务资源都预留成功,那么进入 Confirm 步骤,提交各个子业务服务,完成实际的业务处理,否则进入 Cancel 步骤,取消资源预留请求。

与 2PC/XA 两阶段提交的区别

  • 2PC/XA 是数据库或者存储资源层面的事务,实现的是强一致性,在两阶段提交的整个过程中,一直会持有数据库的锁。
  • TCC 关注业务层的正确提交和回滚,在 Try 阶段不涉及加锁,是业务层的分布式事务,关注最终一致性,不会一直持有各个业务资源的锁。

TCC 的核心思想是针对每个业务操作,都要添加一个与其对应的确认和补偿操作,同时把相关的处理,从数据库转移到业务中,以此实现跨数据库的事务。

TCC 分布式服务组件

在业务中引入 TCC 一般是依赖单独的 TCC 事务框架,可以选择自研或者应用开源组件。TCC 框架扮演了资源管理器的角色,常用的 TCC 开源组件有 Tcc-transaction、ByteTCC、Spring-cloud-rest-tcc 等。

前面介绍过的 Seata,可以选择 TCC 事务模式,也支持了 AT 模式及 Saga 模式。

以 Tcc-transaction 为例,源码托管在 Github-tcc-transaction,提供了对 Spring 和 Dubbo 的适配,感兴趣的话可以查看 tcc-transaction-tutorial-sample 学习。

image (2).png

总结

本文介绍了 TCC 分布式事务模型的应用,通过一个实际例子分析了如何应用 TCC 对业务系统进行改造,并且对比了 TCC 和 2PC 两阶段提交,以及 TCC 相关的开源组件。

相关文章:

如何在业务中体现TCC事务模型?

在分布式系统设计中,随着微服务的流行,通常一个业务操作被拆分为多个子任务,比如电商系统的下单和支付操作,就涉及到了创建和更新订单、扣减账户余额、扣减库存、发送物流消息等,那么在复杂业务开发中,如何…...

TouchGFX字库外置的另一种处理方式

最近有个带UI的项目,采用STM32F429做主控方案,对比touchgfx、lvgl和emwin,发现TouchGFX性能最好,并且界面设计工具也很好用,于是选择此图形引擎。 最开始是熟悉UI设计工具,需要一个表格控件,无…...

jvm的垃圾回收算法有哪些

jvm的垃圾回收算法有标记-清除、复制、标记-整理、分代回收算法,它们分别有不同的实现: 一、标记-清除算法 利用可达性分析算法分析之后,将未被标记的对象[即不可达对象]清除,以便回收它们所占用的内存。 缺点: 1、需…...

untiy 连接两个UI或一段固定一段跟随鼠标移动的线段

注意,仅适用于UI,且Canvas必须是Camera模式,不能用在3D物体上,3D物体请使用LineRenender 先创建一个图片,将锚点固定在左边 然后在脚本中添加如下内容 public RectTransform startObj;//起点物体public RectTransfor…...

如何成为顶级开源项目的贡献者

概述 对于程序员来讲,成为顶级开源项目的贡献者是一件有意义的事,当然,这也绝非易事。如果你正从事人工智能有关的工作,那么你一定了解诸如Google Tensorflow,Facebook Pytorch这样的开源项目。下面我们就说一说如何成…...

Threads and QObjects

QThread inherits QObject. It emits signals to indicate that the thread started or finished executing, and provides a few slots as well. QThread 派生于 QObject。QThread 会发射信号通知线程启动或终止执行任务,并且也会提供槽函数使用。 More interest…...

Tcp是怎样进行可靠准确的传输数据包的?

概述 很多时候,我们都在说Tcp协议,Tcp协议解决了什么问题,在实际工作中有什么具体的意义,想到了这些我想你的技术会更有所提升,Tcp协议是程序员编程中的最重要的一块基石,Tcp是怎样进行可靠准确的传输数据…...

[SWPUCTF 2022 新生赛]numgame

这道题有点东西网页一段计算框,只有加和减数字,但是永远到大不了20,页面也没啥特别的,准备看源码,但是打不开,我以为是环境坏掉了,看wp别人也这样,只不过大佬的开发者工具可以打开&a…...

java异常机制分析

java异常机制分析 本文实例分析了java的异常机制,分享给大家供大家参考。相信有助于大家提高大家Java程序异常处理能力。具体分析如下: 众所周知,java中的异常(Exception)机制很重要,程序难免会出错,异常机制可以捕获…...

浅谈Python中的内存管理 程序的内存布局

Python中的内存管理 Python 的内存管理是通过私有堆空间来实现的。这个私有堆内存中存储了所有 Python 对象和数据结构。Python 的解释器自身则拥有对堆空间的访问权,程序员不能直接访问这个私有堆,但可以通过解释器的 API 来进行某些操作。 以下是 Py…...

(具体解决方案)训练GAN深度学习的时候出现生成器loss一直上升但判别器loss趋于0

今天小陶在训练CGAN的时候出现了绷不住的情况,那就是G_loss(生成器的loss值)一路狂飙,一直上升到了6才逐渐平稳。而D_loss(判别器的loss值)却越来越小,具体的情况就看下面的图片吧。其实这在GAN…...

Redis 安装以及配置隧道连接

目录 1.CentOS 1. 安装Redis 2. Redis 启动和停⽌ 3. 操作Redis 2.Ubuntu 1. 安装Redis 2. Redis 启动/停⽌ 3. 操作 Redis 3.开启隧道 3.1 Xshell 配置隧道 3.2 windTerm 配置隧道 3.3 FinalShell配置隧道 4.可视化客户端连接 Another Redis Desktop Manager 1.Cen…...

FFmpeg 使用总结

FFmpeg 简介 FFmpeg的名称来自MPEG视频编码标准,前面的“FF”代表“Fast Forward”,FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。可以轻易地实现多种视频格式之间的相互转换。包括如下几个部分&#xf…...

出现Error: Cannot find module ‘compression-webpack-plugin‘错误

错误: 解决:npm install --save-dev compression-webpack-plugin1.1.12 版本问题...

Elasticsearch 摄取管道 — 检测到管道的死循环

在数据处理和摄取领域,管道在组织和自动化数据从源到目的地的流动方面发挥着至关重要的作用。 管道是数据按顺序通过的一系列处理阶段,每个阶段负责特定任务。 然而,有时,管道可能会遇到一个重大挑战,称为 “Cycle det…...

C# ListBox自动滚动方法

1、方法1:添加记录后,选择最后一条记录,让滚动条滚动到底部,再自动取消 listBox1.Items.Add(t ":a good day"); listBox1.SelectedIndex listBox1.Items.Count - 1; listBox1.SelectedIndex -1; //是否取消选中行…...

使用(Ajax原理)Promise + XHR实现请求数据

使用Promise XHR获取省份列表 步骤&#xff1a; * 1. 创建Promise对象 * 2. 执行XHR异步代码&#xff0c;获取省份列表 * 3. 关联成功或失败函数&#xff0c;做后续处理 代码示例 <script>// 1. 创建Promise对象const p new Promise((resolve,reject) > {// 2. 执行…...

【HTML】<input>

分类 text password number button reset submit hidden radio checkbox file image color range tel email&#xff08;火狐有校验&#xff0c;360浏览器无校验。&#xff09; url datetime&#xff08;火狐、360浏览器不支持&#xff09; search date、month、week、time、da…...

数据结构中一些零碎且易忘的知识点

树 并查集&#xff1a; 并查集的应用&#xff1a; 判断连通性、判环Kruskal算法排序并查集 并查集的存储方式 逻辑&#xff1a;双亲表示法的树存储&#xff1a;数组 并查集的时间复杂度&#xff08;m为并查集长度&#xff09; find&#xff1a;优化前为 O ( m ) O(m) O(m)&…...

2023上半年京东烘干机行业品牌销售排行榜(京东商品数据)

随着人们消费水平的提高&#xff0c;追求健康品质消费的用户越来越多&#xff0c;这样的消费升级为市场的发展带来很大的动力。同时&#xff0c;随着洗衣机市场趋向饱和&#xff0c;增长趋于平缓&#xff0c;更新换代和结构升级成为行业的主旋律。 在这一市场背景下&#xff0…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...