Go微服务: 关于TCC分布式事务

news2024/11/16 17:53:53

TCC 分布式事务

  • T: Try 预处理, 尝试执行,完成所有的业务检查,做好一致性,预留必要的业务资源,做好准隔离性
  • C: Confirm 确认,如果所有的分支Try都成功了, 就到了这个阶段, Confirm 是真正执行业务的过程, 不做任何业务检查, 只使用 try 阶段预留的业务资源
  • C: Cancel 取消,所有的分支中,如果有一个失败了,则走到 Cancel 的阶段,Cancel 就释放了 Try 阶段预留的业务资源
  • 所以,Confirm 和 Cancel 是互斥的,只会执行一个,按照TCC的协议,Confirm 和 Cancel 只返回成功,不返回失败
  • 如果有网络问题,或服务器临时故障, 比如崩溃,掉电这种, 事务管理器会进行重试,最终让他成功
  • 在 Try 阶段要做业务检查,保障一致性以及资源预留隔离的一些问题
  • 此阶段只是一个初步的操作, 它和后续的Confirm一起才能真正构成完整的业务逻辑, 这个算是一部分,当所有的 Try 都完成了,就会向下执行,到Confirm
  • Confirm 阶段做一个确认提交, Try 阶段的所有分支事务执行成功后, 开始执行 Confirm, 采用TCC时候,只要Try 成功了,就表示Confirm 阶段不会出错,如果 Confirm 阶段出错,就引入重试机制, 或者人工处理
  • 上图是在 Try 阶段, 资源2执行失败,资源1执行成功, 要回滚资源1,这时候资源1要回滚,就是执行 Cancel, 业务执行错误,需要回滚,执行分支的事务的业务取消,预留资源的释放,一般认为Cancel阶段也是一定成功的, 如果Cancel 出错,也是重试机制和人工处理
  • 上面全局事务发起方是全局事务的管理器,是独立的第三方,可以实现独立的服务,会生成全局的事务记录,全局的事务id贯穿整个分布式事务的调用链,类似 jaeger 的链路追踪traceID,都是分布式的产品,这些产品设计思路都是相互借鉴,所以,这个全局事务管理器可以追踪和调用状态,由于 Confirm 和 Cancel 失败需要进行重试, 所以要实现幂等性,也就是说同一个操作,无论请求多少次,结果都应该是相同的
  • TCC 的三种异常处理:空回滚,幂等,悬挂
    • 1 )空回滚:在没有调用 Try 阶段的方法而调用了第二阶段的 Cancel 方法
    • Cancel 方法要识别出这是一个空回滚, 然后直接返回成功
    • 也就是说空回滚在某种情况下,没有执行 Try, 就直接回滚了
    • 2 )幂等:为了保证TCC的二阶段提交重试机制不会引发数据不一致
    • 就要求TCC的二阶段Try, Confirm, Cancel 接口保证幂等,这样不会重复使用或者释放资源,如果幂等没有控制做好,就很容易导致数据不一致的严重问题
    • 解决思路是增加执行状态,每次执行前,就要查询状态,这就是说你能不能证明你的状态执行到哪里了,可以做一个记录
    • 3 )悬挂:对于一个分布式事务,二阶段的Cancel接口比Try接口先执行了
    • 悬挂对于分布式的二阶段,Cancel 接口比Try接口先执行
    • 对比空回滚是Try是不执行;而悬挂是Cancel先执行,Try再执行
    • 它的解决思路是,如果二阶段执行成功,一阶段就不能再继续执行了,在执行一阶段事务时要判断一下,全局事务是否已经有二阶段事务的记录,如果有,就不执行Try了

TCC 为何这么难?


1 ) 从代码上来说

  • 可以把我们的TCC放到我们的代码,或者说放到一些场景里来看一下
  • 好,我们先从代码说起, 那我们在这里先新建一个目录,就叫 TCC Demo
  • 按照TCC的规则来,我们每一个方法函数都需要有这三个函数: Try, Confirm, Cancel
  • 比如订单业务,有三个函数
    • func TryOrder() {}
    • func ConfirmOrder() {}
    • func CancelOrder() {}
  • 比如下单的时候,需要协同构建库存,增加积分
  • 对于库存来说, 有:
    • func TryStock(){}
    • func ConfirmStock(){}
    • func CancelStock(){}
  • 对于积分来说,有:
    • func TryPoint(){}
    • func ConfirmStock(){}
    • func CancelOrder(){}
  • 如果我们业务中有10个这种,那么我们要写30个这类服务,而且需要有数据库的配合,非常的繁琐

2 ) 基于业务场景来看

  • 先看左边的订单服务,它有自己的这个mysql数据库。它第一步先启动事物和这个TCC事务管理器去交互
  • 它启动事物之后,第二步就调用这个Try,调用所有的资源上的Try
  • 第三步就是要执行提交或者回滚,现在,我们的Try都是ok的
  • 下面它就要执行第四步,这第四步的这个Confirm和Cancel是互斥的, 只能择其一执行
  • 因为你这个Try执行成功了,就直接都是 confirmStock 和 confirmPoint
  • 如果要是有问题,中间可能就是 CancelStock 和 CancelPoint
    在实际开发中一般是一个什么样的情况呢?
    • 就是说 Try 一般是执行主业务的, 比如我们有一个非常难的业务, 在try里基本都搞定了
    • 那对于这个 Confirm和Cancel, 它一般都是基本是比较简单的操作
    • 其实一般只要Try里没有问题, 那么Confirm和这个Cancel就基本上可以认为是没有太大问题,但是还有其他的问题
    • 并不是说,Try ok了,然后 Confirm OK了,Cancel 也 ok 了,就没有问题
    • 分布式的复杂,它是存在各种问题的,比如说你这个分布式网络,你永远不要相信分布式里网络永远是好的
    • 或者说我现在这个库存有另一个小组维护,这个库存它没有问题,但是我们这个积分服务挂了,或者说很慢
    • 我们说这个库存服务,还有这个积分服务,都是其他小组维护的,我们站在我们这个订单角度来说,比如说我是订单服务的负责人
    • 那我不能说动人家这个积分服务的这个代码,比如说积分服务,是挂了或者处理很慢
    • 就要去看这个TCC的事务管理器了,其实这个TCC在开启事务之前,它会详细的记录日志
    • 它有一个日志,每个服务调用了哪个接口,当前事务执行到哪里?
    • 比如,即便积分服务挂了,重启了,对吧?重启以后,我们找到日志,找到这个日志仍然可以继续执行
    • 假如,我们的积分服务 Cancel 执行这个出错了, 那么我们的TCC事务会一直重试
    • 那么TCC事务管理器,要保证执行Cancel不出错,它就会重试。
    • 这样一来就可以解决大部分的网络带来的这个问题
    • 因为Cancel, Confirm, 这里面的这个业务逻辑基本不是很复杂
    • 可能改个状态,或者是添加个什么东西,就是这种类型的,它可能就是网络抖动, 给你造成了一下这个小麻烦
    • 那你你这个重试几次之后呢,补偿一下就可以
    • 从这儿可以看到TCC事务管理器控制整个流程
  • 我们调用TCC,如果Try阶段有问题,那TCC框架就会执行服务的Cancel逻辑撤销之前的操作
  • 如果,我们调用这个TCC如果Try阶段它就有问题,比如说你的这个业务太复杂了,在某个地方突然出了一个小bug
  • 那么TCC框架就会执行各种Cancel逻辑撤销之前的操作
  • 如果上图这个Confirm或Cancel它就是一直不成功,怎么办?
  • 其实分布式它本身虽然比较复杂,但是大部分业务的Confirm和Cancel代码就是很简单
  • 一般的都是网络问题,通过一直调用的进行补偿就可以了
  • 如果一直不成功,你可以在某种程度上做一个记录器进行报警,人为干预
  • 自己做的计录器可以按你自己的业务逻辑,因为你这个TCC事务,比如三次或五次都不成功,它要保证成功,则可以通过电话,微信,钉钉通知人报警
  • 这时候,比如说开发人员肯定是收到了嘛,人为介入解决这个问题就行了嘛
  • 所以,其实TCC真的是不简单,我们只要使用了微服务和这个分布式,就没有办法避免没有这些问题,只要你用了就会遇到这些问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1800211.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国产Sora免费体验-快手旗下可灵大模型发布

自从OpenAI公布了Sora后,震爆了全世界,但由于其技术的不成熟和应用的局限性,未能大规模推广,只有零零散散的几个公布出来的一些视频。昨日,快手成立13周年,可灵(Kling)大模型发布&am…

BGP汇总+认证

一、BGP 的宣告问题 1、在 BGP 协议中每台运行 BGP 的设备上,宣告本地直连路由 2、在 BGP 协议中运行 BGP 协议的设备来宣告.通过 IGP 学习到的,未运行 BGP 协议设备产2、生的路由; 在 BGP 协议中宣告本地路由表中路由条目时,将携带本地到达这…

Facebook企业户 | Facebook公共主页经营

Facebook作为社交媒体巨头,拥有庞大的用户基数,因此,有效经营公共主页是获取持续流量、提升客户信任度和粘性、促进产品或服务销售与转化的关键。要优化Facebook主页,关注以下几点: 1、参与度是关键指标:因…

LAMPSECURITY: CTF4 靶机实战

信息收集: 存活扫描: 端口扫描: 服务扫描: web页面: blog页面发现注入点: sql注入: sqlmap一把梭: 多个参数记得打: 哦 ssh登录: 老版本的ssh,…

Spring 之 Lifecycle 及 SmartLifecycle

最近在看Eureka源码,本想快速解决这场没有硝烟的战役,不曾想阻塞性问题一个接一个。为正确理解这个框架,我不得不耐着性子,慢慢梳理这些让人困惑的点。譬如本章要梳理的Lifecycle和SmartLifecycle。它们均为接口,其中后…

【Lua】IntelliJ IDEA 写注释或选中变量单词时偶尔会选中相邻的内容或下一行内容

例如: --UI代码local a 0 当你想在a变量上方加一行 --UI代码注释时,会发现敲打daima中文拼音时(还未按回车)就会选中当前行以及下一行前半部分。 打完按空格就会变成这样子! 原因是因为开启了英文检测,需要关掉它。 …

云南区块链商户平台发票助手成品

目录 1 概述2 功能对比3 项目演示图4 核心逻辑4.1智能赋码4.2 解密方法4.3 登录与检测4.4 发票金额大写转换4.5 检查登录是否失效4.6 验证码识别5 演示效果6 项目部署6.1 Web站点部署6.1.1 环境6.1.2 前端6.1.3 后端6.2 Docker部署6.2.1 构建镜像6.2.2 创建容器6.3.3 访问项目域…

算法2:滑动窗口(下)

文章目录 水果成篮找到字符串中所有字母异位词串联所有单词的子串*最小覆盖子串* 水果成篮 两元素排空操作 窗口中存在元素交错情况&#xff0c;所以出窗口一定要出干净&#xff01;&#xff01;&#xff01; class Solution { public:int totalFruit(vector<int>& …

VS2019创建c++动态链接库dll与调用方法

VS2019创建c动态链接库dll与调用方法 1.点击文件-》新建-》项目&#xff0c;输入dll,选择具有导出项的(DLL)动态链接库 2.输入一个文件名&#xff1a;dll2 头文件.h 3.添加加减法函数&#xff1a; // 下列 ifdef 块是创建使从 DLL 导出更简单的 // 宏的标准方法。此 DLL 中的…

【雷达原理】一维CFAR检测算法——对比分析与代码实现

目录 引言一、仿真实例1.1 均匀背景杂波1.2 杂波边缘1.3 多干扰目标杂波 二、MATLAB代码参考文献 引言 推荐博文【目标检测】雷达目标CFAR检测算法 上述文章介绍了四种典型CFAR检测算法的特点及性能对比。本文将利用MATLAB进行仿真&#xff0c;通过实例验证和对比这几种算法的…

MFC 使用sapi文字转换为语音

文章目录 添加头文件声明变量 添加头文件 声明变量 pSpVoice NULL; //默认构造函数中初始化为空 bool CChKBarSCCodeApp::InitSpVoice() {HRESULT hr ::CoInitialize(NULL); // COM初始化if (!SUCCEEDED(hr)){AfxMessageBox(_T("声音环境初始化失败&#xff01;…

拼接屏处理器

拼接屏系统由三大部分组成&#xff0c;即拼接墙、液晶拼接处理器和信号源。其中液晶拼接处理器是关键技术的核心&#xff0c;支持不同像素的图像在大屏显示墙上显示以及在大屏显示墙上任意开窗口、BSV画面叠加、窗口放大缩小、跨屏漫游显示等。液晶拼接处理器一般分为两种&…

【grafana】创建多变量table

这个普罗米修斯的指标啊&#xff0c;大多数都是键值对&#xff0c;而且笔者如果没记错&#xff0c;他这个值还必须是浮点。少数可以设成离散值&#xff08;Enum&#xff09;&#xff0c;但本质还是一个带翻译功能的键值对 这样的好处是&#xff0c;做起来非常简单&#xff0c;…

利用梯度提升树分类法实现乳腺癌数据集分类

目录 1. 作者介绍2. 梯度提升树算法2.1 Boosting 算法2.2 Boosting Tree &#xff08;提升树&#xff09;2.3 梯度提升树&#xff08;Gradient Boosting Tree&#xff09; 3. 利用梯度提升树分类法实现乳腺癌数据集分类实验3.1 乳腺癌数据集介绍3.2 实验过程3.3 实验结果3.4 完…

突破语言与文化壁垒:海外短剧推广平台多语言支持技术的重要性与实施

在全球化的今天&#xff0c;语言和文化差异成为了海外短剧推广的一大挑战。为了吸引全球观众&#xff0c;海外短剧推广平台必须提供多语言支持&#xff0c;以突破语言与文化壁垒。本文将强调多语言支持的重要性&#xff0c;并探讨其实现技术。 一、多语言支持的重要性 随着全…

[网鼎杯 2020 青龙组]jocker

运行程序,发现是要我们自己输入 那么肯定是拿到enc慢慢还原 32位,无壳 进来就红一下报错 这里可以看见长度为24 动调一下看看 这里进行了大量的异或 这里是对地址开始的硬编码进行异或,从而达到smc的效果 所以你也可以发现在进行这一步操作之前 encry函数全是报错 你点开…

经纬恒润助力红旗转向技术新突破

近日&#xff0c;红旗研发新视界发布《国内首发&#xff01;红旗大输出力冗余平行轴式电动助力转向器让用户出行经济又安全&#xff01;》 &#xff0c;创新突破“输出力20kN以上的冗余平行轴式电动助力转向器&#xff08;R-EPS&#xff09;”。该产品支持整车实现L2/L3级自动驾…

苹果Safari怎么清理缓存?原来快速清除浏览器的历史记录那么容易

在数字化时代&#xff0c;互联网已经成为我们日常生活中不可或缺的一部分。我们使用各种设备&#xff0c;如智能手机、平板电脑和笔记本电脑来浏览网页、获取信息、娱乐和社交。而在这些设备中&#xff0c;iPhone无疑是最受欢迎的选择之一。iPhone搭载的Safari浏览器以其简洁的…

AIConnect赋能加持丨AI+DEPIN 共同推动AI发展的技术与运用峰会圆满落幕

6月6日&#xff0c;由AIConnect主办&#xff0c;JuCoin协办的「AIDePIN 共同推动AI发展的技术与应用」峰会在胡志明市圆满落幕&#xff01;此次活动不仅是AIConnect生态在市场推广和技术应用方面的重要一步&#xff0c;也标志着JuCoin在推动AI与DePIN技术融合中的又一里程碑。 …

车载开发之预置无源码apk到Android系统(带so文件)

1.在 packages/apps 下面以需要预置的 APK 名字创建文件夹&#xff0c;以预置一个名为 CarNavi 的APK为例。 新建一个CarNavi 的文件夹&#xff0c;在系统里面&#xff0c;如下图所示&#xff08;我的系统路径&#xff1a;/home/ts/project/NewAosp/Android/packages/apps/Car…