分布式事务解决方案——TCC
TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。
1、Try 阶段是做业务检查(一致性)及资源预留(隔离),此阶段仅是一个初步操作,它和后续的Confirm一起才能真正构成一个完整的业务逻辑。
2、Confirm 阶段是做确认提交,Try阶段所有分支事务执行成功后开始执行Confirm。通常情况下,TCC认为Confirm阶段是不会出错的,若Confirm阶段真的出错了,则重试或人工处理。
3、Cancel 阶段是在业务执行错误需要回滚的状态下执行分支事务的业务取消,预留资源释放。通常情况下,TCC认为Cancel阶段也是一定成功的,若Cancel阶段真的出错了,则重试或人工处理。
TM(事务管理器)首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作;若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel操作若执行失败,TM会进行重试。
所有try都成功

有一个try失败

特别提醒
所有分支事务的try阶段执行成功,则会执行confirm阶段。TCC认为confirm阶段一定会执行成功,如果confirm执行失败,则会重试或者人工处理错误。
任何一个分支事务的try阶段执行失败,则会执行cancel阶段。TCC认为cancel阶段一定会执行成功,如果cancel执行失败,则会重试或者人工处理错误。
TCC需要注意三种异常处理分别是:空回滚、幂等、悬挂。
空回滚

事务管理器调用服务的try操作,可能会出现因为丢包而导致的网络超时,导致应用的try阶段没执行,事务管理器认为执行try超时,会触发cancel操作。这就导致cancel比try先执行。
悬挂

1、事务协调器在调用 TCC 服务的一阶段 Try 操作时,可能会出现因网络拥堵而导致的超时。
2、此时事务管理器会触发二阶段回滚,调用 TCC 服务的 Cancel 操作,Cancel 执行正常。
3、在此之后,拥堵在网络上的一阶段 Try 数据包被 TCC 服务收到,出现了二阶段 Cancel 请求比一阶段 Try 请求先执行的情况。
4、此 TCC 服务在执行晚到的 Try 之后,将永远不会再收到二阶段的 Confirm 或者 Cancel ,造成 TCC 服务悬挂。
幂等
try、confirm、cancel都会被重复调用,需要做幂等处理。
处理空回滚、悬挂、幂等
可以使用日志表,来解决 空回滚、悬挂、幂等。
新建3张表
try阶段日志表local_try_log | |
字段 | 注释 |
tx_no | 全局事务id |
create_time | 创建时间 |
confirm阶段日志表local_confirm_log | |
字段 | 注释 |
tx_no | 全局事务id |
create_time | 创建时间 |
cancel阶段日志表local_cancel_log | |
字段 | 注释 |
tx_no | 全局事务id |
create_time | 创建时间 |
例子
从银行1转账10元给银行2,使用TCC方案
方案1
银行1
try:幂等校验,查找try日志(全局事务id是主键)悬挂处理,查找confirm、cancel日志(全局事务id是主键)检查余额是否够10元锁定10元插入try日志(全局事务id是主键)
confirm:幂等校验,查找confirm日志(全局事务id是主键)扣减10元删除锁定10元插入confirm日志(全局事务id是主键)
cancel:cancel幂等校验,查找cancel日志(全局事务id是主键)空回滚处理,查找try日志(全局事务id是主键)增加余额10元(回滚)删除锁定10元插入cancel日志(全局事务id是主键)银行2
try:幂等校验,查找try日志(全局事务id是主键)悬挂处理,查找confirm、cancel日志(全局事务id是主键)插入待激活10元插入try日志(全局事务id是主键)
confirm:幂等校验,查找confirm日志(全局事务id是主键)正式增加30元删除待激活10元插入confirm日志(全局事务id是主键)
cancel:空由于业务很简单,上面的流程还可以取消锁定,解锁的操作,直接在银行1的try中扣减10元,流程如下。
方案2
银行1
try:幂等校验,查找try日志(全局事务id是主键)悬挂处理,查找confirm、cancel日志(全局事务id是主键)检查余额是否够10元扣减10元插入try日志(全局事务id是主键)
confirm:空
cancel:cancel幂等校验,查找cancel日志(全局事务id是主键)空回滚处理,查找try日志(全局事务id是主键)增加余额10元(回滚)插入cancel日志(全局事务id是主键)银行2
try:空
confirm:幂等校验,查找confirm日志(全局事务id是主键)正式增加30元插入confirm日志(全局事务id是主键)
cancel:空Hmily实现方案2的代码
服务1
@Service
@Slf4j
public class Bank1ServiceImpl implements Bank1Service {@AutowiredAccountInfoDao accountInfoDao;@AutowiredHmilyLogDao hmilyLogDao;@AutowiredBank2Client bank2Client;@Override@Transactional(rollbackFor = Exception.class)@Hmily(confirmMethod = "confirm", cancelMethod = "cancel")public void updateAccountBalance(String msg, Double amount) {// 全局事务idString transId = HmilyTransactionContextLocal.getInstance().get().getTransId();log.info("bank1 try 开始,transId={}", transId);// 幂等判断int existTry = hmilyLogDao.isExistTry(transId);// 通故全局事务id查找到try日志,表明已经只执行过tryif (existTry > 0) {log.info("已经执行过try,无需重复执行try,transId={}", transId);return;}// 悬挂处理int existConfirm = hmilyLogDao.isExistConfirm(transId);int existCancel = hmilyLogDao.isExistCancel(transId);// 通故全局事务id查找到confirm、cancel日志,表明已经只执行过confirm、cancelif (existConfirm > 0 || existCancel > 0) {log.info("confirm,cancel有一个已经执行过,try不能再次执行,transId={}", transId);return;}// 制造空回滚if (StringUtils.equals("制造空回滚", msg)) {throw new RuntimeException("try方法没修改数据库就抛出异常,cancel方法会执行,形成空回滚,transId=" + transId);}// blank1减金额accountInfoDao.subtractAccountBalance("1", amount);// 添加try日志记录,try日志和扣减余额在同一个本地事务中,要么都成功,要么都失败// 日志的组件id必须是全局事务id,如果同一个事物重复调用try,到这一步会报主键重复hmilyLogDao.addTry(transId);// 远程调用Boolean result = bank2Client.transfer(msg, amount);if (!result) {throw new RuntimeException("调用bank2失败");}// bank1调用bank2成功后,发生异常,模拟回滚if (StringUtils.equals("bank1调用bank2成功后,发生异常,模拟回滚", msg)) {throw new RuntimeException("bank1调用bank2成功后,发生异常,模拟回滚,transId=" + transId);}}public void confirm(String accountNo, Double amount) {String transId = HmilyTransactionContextLocal.getInstance().get().getTransId();log.info("bank1 confirm 开始执行,transId={}", transId);}@Transactional(rollbackFor = Exception.class)public void cancel(String msg, Double amount) {// 全局事务idString transId = HmilyTransactionContextLocal.getInstance().get().getTransId();log.info("bank1 cancel 开始执行,transId={}", transId);// 幂等判断int existCancel = hmilyLogDao.isExistCancel(transId);if (existCancel > 0) {log.info("cancel已经执行过,无需重复执行,transId={}", transId);return;}// 处理空回滚int existTry = hmilyLogDao.isExistTry(transId);if (existTry == 0) {log.info("try未执行过,不能执行cancel,transId={}", transId);return;}// bank1回滚,加钱accountInfoDao.addAccountBalance(msg, amount);// 添加日志hmilyLogDao.addCancel(transId);}}
@Service
@Slf4j
public class Bank2ServiceImpl implements Bank2Service {@AutowiredAccountInfoDao accountInfoDao;@AutowiredHmilyLogDao hmilyLogDao;@Override@Hmily(confirmMethod = "confirm", cancelMethod = "cancel")public void updateAccountBalance(String msg, Double amount) {String transId = HmilyTransactionContextLocal.getInstance().get().getTransId();log.info("bank2 try 开始执行,transId:{}",transId);}@Transactional(rollbackFor = Exception.class)public void confirm(String msg, Double amount) {// 全局事务idString transId = HmilyTransactionContextLocal.getInstance().get().getTransId();log.info("bank2 confirm 开始执行,transId:{}",transId);int existConfirm = hmilyLogDao.isExistConfirm(transId);if (existConfirm > 0) {log.info("bank2 confirm 已经执行过,无需再次执行,transId", transId);return;}// bank2加钱accountInfoDao.addAccountBalance("2", amount);// 添加confirm日志hmilyLogDao.addConfirm(transId);// bank2 confirm,抛出异常,会重试if (StringUtils.equals("confirm抛出异常会重试", msg)) {throw new RuntimeException("confirm抛出异常会重试,transId=" + transId);}}public void cancel(String msg, Double amount) {String transId = HmilyTransactionContextLocal.getInstance().get().getTransId();log.info("bank2 cancel 开始执行,transId:{}",transId);}}
相关文章:
分布式事务解决方案——TCC
TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。1、Try 阶段是做业务检查(一致性)及资源预留(隔离),此阶段仅是一个初步操作,它和后续的Confirm一起才能真正构成…...
ITSS认证分为几个级别,哪个级别最高
一、什么是ITSS ITSS( 信息技术服务标准,简称ITSS)是国内第一套成体系和综合配套的信息技术服务标准库,全面规范了IT服务产品及其组成要素,用于指导实施标准化和可信赖的IT服务。 ITSS是在工业和信息化部、国家标准化管理委员会的联合指导下…...
ZigBee案例笔记 - USART
文章目录1.串行通信接口简述2.串行通信接口寄存器U0CSR (0x86) -USART 0 控制和状态U0UCR (0xC4)–USART 0 UART 控制U0GCR (0xC5)–USART 0 通用控制U0BUF (0xC1) – USART 0 接收/传送数据缓存U0BAUD (0xC2) – USART 0 波特率控制3.设置串行通信接口比特率控制寄存器4.外设I…...
java | 基于Redis的分布式锁实现①
前言 首先,为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件: 互斥性。在任意时刻,只有一个客户端能持有锁。不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户…...
十六、基于FPGA的CRC校验设计实现
1,CRC校验循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误。它是利用除法及余数的…...
2022爱分析 · DataOps厂商全景报告 | 爱分析报告
报告编委 李喆 爱分析合伙人&首席分析师 廖耘加 爱分析分析师 目录 1. 研究范围定义 2. 市场洞察 3. 厂商全景地图 4. 市场分析与厂商评估 5. 入选厂商列表 1. 研究范围定义 研究范围 在后疫情时代,以数据分析为代表的数据消费场景日益丰富&…...
京东前端react面试题及答案
useEffect 与 useLayoutEffect 的区别 (1)共同点 运用效果: useEffect 与 useLayoutEffect 两者都是用于处理副作用,这些副作用包括改变 DOM、设置订阅、操作定时器等。在函数组件内部操作副作用是不被允许的,所以需…...
TongWeb8数据源相关问题
问题一:数据源连接不足当TongWeb数据源连接用完时,除了监控中看到连接占用高以外,日志中会有如下提示信息。2023-02-14 10:24:43 [WARN] - com.tongweb.web.jdbc.pool.PoolExhaustedException: [TW-0.0.0.0-8088-3] Timeout: Pool empty. Una…...
关于最近大热的AI,你怎么看?
AI人工智能,相信大家都不陌生,也都接触过不少。但是最近小编在网上冲浪的时候发现各大媒体又掀起了一阵AI热潮,AI不是很常见了吗?是又有什么新的发展吗? 带着强烈的好奇心,我在地铁上读完了一篇关于Chatgp…...
25.架构和软件产品线
文章目录25 Architecture and Software Product Lines架构和软件产品线25.1 An Example of Product Line Variability 产品线可变性的一个例子25.2 What Makes a Software Product Line Work? 软件产品线的工作原理是什么?25.3 Product Line Scope 产品线范围25.4 …...
Seata-server 源码学习(一)
Seata源码学习引入 学习了Seata的应用以后,我们从这开始要开始分析Seata的源码相关内容 源码下载 官方地址:https://seata.io/zh-cn/blog/download.html 通过idea打开seata-1.4.2版本的源码 回顾AT模式 其实在之前的应用课程中,我们已经用…...
2023新华为OD机试题 - 斗地主(JavaScript)
斗地主 题目 斗地主起源于湖北十堰房县, 据传是一位叫吴修全的年轻人根据当地流行的扑克玩法“跑得快”改编的, 如今已风靡整个中国,并流行于互联网上 牌型: 单顺,又称顺子,最少5张牌,最多12张牌(3...A),不能有2, 也不能有大小王,不计花色 例如:3-4-5-7-8,7-8-9-1…...
素数相关(结合回文数,合数)线性筛素数(欧拉筛法)Euler【算法模板笔记】
一、朴素筛法(埃拉托斯特尼筛法)Eratosthenes 筛法(埃拉托斯特尼筛法,简称埃氏筛法)时间复杂度是O(nloglogn)不常用,被欧拉筛代替,略二、线性筛素数(欧拉筛法)简介线性筛…...
1.7配置OSPF手动汇总
实验7:配置OSPF手动汇总 实验目的实现OSPF路由汇总的配置阐明OSPF引入的外部路由时进行路由汇总的方法实验拓扑配置OSPF手动汇总实验拓扑如图1-17所示。 图1-17 配置OSPF手动汇总 实验步骤配置IP地址,配置OSPF(和实验6一致,此处略)在…...
多线程下载工具axel的安装和使用
多线程下载工具axel的安装和使用 Axel是一个轻量级下载程序,它和其他加速器一样,对同一个文件建立多个连接,每个连接下载单独的文件片段以更快地完成下载。 Axel 支持 HTTP、HTTPS、FTP 和 FTPS 协议。它也可以使用多个镜像站点下载单个文件…...
大数据专业职业前景如何
大数据专业毕业生未来的岗位选择空间比较大,有三大类岗位可选择分别是大数据开发岗位、大数据分析岗位和大数据运维岗位,在不同的行业和技术体系结构下这些岗位也包含很多细分的岗位。 大数据开发岗位分为平台研发岗位和行业场景开发岗位两大类…...
拉格朗日乘数法在原材料选择问题上的具体应用
问题需求: 输入待制作的材料:(材料长,材料数量) 分别为(5401,124)、(200,135)、(1350,45), 输入原材料长度最大值6500,最小值3500&…...
零信任-腾讯零信任iOA介绍(4)
腾讯零信任介绍 腾讯零信任是一种信息安全架构,旨在通过限制对计算设备、数据和应用程序的访问来保护敏感信息。腾讯零信任的主要思想是,任何计算设备、数据或应用程序都不应被自动信任,并需要经过授权后才能访问敏感信息。 腾讯零信任的…...
标准的maven依赖包应该包含哪些东西?
背景在阅读源码的时候,发现有一些maven依赖包里面没有包含pom文件,一些maven依赖包包含,而且除此之外还有一些细微的差异。今天就来聊一下关于一个标准的依赖包应该是什么样子的。一个标准的Maven依赖包通常包含以下文件:Java类文…...
网络安全-Nmap
网络安全-Nmap Nmap-号称诸神之眼 这个呢就是用来扫描网络端口的 Namp的工作原理很像一个雷达 做任何攻击之前,得先知道怎么去找破绽,而不是钢铁洪流,那个是不叫渗透了,叫硬钢。 咋用呢? 很简单 直接 nmap 后面跟网址…...
2026知网AIGC检测算法升级解读:对降AI率有什么影响?
2026知网AIGC检测算法升级解读:对降AI率有什么影响? 2026年春季学期刚开始,知网就放出了一个让无数毕业生心头一紧的消息——AIGC检测系统完成了新一轮算法升级。这次升级并非小修小补,而是从底层检测逻辑到特征识别模型的全面迭代…...
TCP追踪实战指南:突破防火墙的网络诊断技术
TCP追踪实战指南:突破防火墙的网络诊断技术 【免费下载链接】tracetcp tracetcp. Traceroute utility that uses tcp syn packets to trace network routes. 项目地址: https://gitcode.com/gh_mirrors/tr/tracetcp 在网络诊断领域,TCP追踪技术正…...
拒绝返工,绘图小白逆袭方法
科研绘图,常常是许多科研人员心中难以言说的痛。明明实验数据漂亮,逻辑推导严密,却卡在了“画图”这一关。面对学术图表中那些繁琐的规范——字体到底用啥?线宽设置为多少像素最清晰?图例的位置和比例如何协调才美观&a…...
Jasmine漫画浏览器使用指南:打造跨设备的个性化阅读体验
Jasmine漫画浏览器使用指南:打造跨设备的个性化阅读体验 【免费下载链接】jasmine A comic browser,support Android / iOS / MacOS / Windows / Linux. 项目地址: https://gitcode.com/gh_mirrors/jas/jasmine Jasmine漫画浏览器作为一款支持多平…...
资源获取效率提升指南:res-downloader全场景应用解析
资源获取效率提升指南:res-downloader全场景应用解析 【免费下载链接】res-downloader 资源下载器、网络资源嗅探,支持微信视频号下载、网页抖音无水印下载、网页快手无水印视频下载、酷狗音乐下载等网络资源拦截下载! 项目地址: https://gitcode.com/…...
Node.js音乐API开发:零成本构建专业级音乐服务接口
Node.js音乐API开发:零成本构建专业级音乐服务接口 【免费下载链接】NeteaseCloudMusicApiBackup 项目地址: https://gitcode.com/gh_mirrors/ne/NeteaseCloudMusicApiBackup 价值定位:为什么选择网易云音乐API服务? 【开发效率倍增…...
Windows Defender Remover工具:系统防护彻底卸载指南
Windows Defender Remover工具:系统防护彻底卸载指南 【免费下载链接】windows-defender-remover A tool which is uses to remove Windows Defender in Windows 8.x, Windows 10 (every version) and Windows 11. 项目地址: https://gitcode.com/gh_mirrors/wi/w…...
基于Maxwell设计的750W内转子伺服电机:14极12槽优化方案与成熟生产案例
基于maxwwell设计的经典750W,3000RPM 内转子 私服电机,14极12槽,外径76 轴向长度56.7 ,转矩1Nm,直流母线12V,辅助槽优化了齿槽转矩,特色是转子加工方便,永磁同步电机(PMSM BLDC&…...
能耗优化方案:OpenClaw+nanobot的笔记本电脑省电配置
能耗优化方案:OpenClawnanobot的笔记本电脑省电配置 1. 为什么需要关注OpenClaw的能耗问题 作为一个长期使用OpenClaw进行自动化办公的用户,我最近遇到了一个棘手的问题:笔记本电池续航急剧下降。经过排查发现,OpenClaw在后台运…...
AI赋能创作:9款工具让选题更智能、降重更轻松
工具对比排名表格 工具名称 核心功能 突出优势 Aibiye 降AIGC率 适配高校规则,AI痕迹弱化 Aicheck 论文降重 速度快,保留专业术语 Askpaper 论文降重 逻辑完整性好 秘塔写作猫 智能降重 结合语法检查 DeepL 多语言降重 翻译改写灵活 知…...
