Seata-TCC快速上手

news2024/11/30 0:32:47

原文链接

如果是小白,可以先看TCC步骤,核心思想,然后使用Seata,阅读Seata官方提供的示例代码,验证自己的猜想,再看遍TCC。

分布式事务是跨过多个数据库或者系统的事务,在电商、金融领域应用十分广泛。TCC方案非常适用于对实时性以及可靠性要求都很高的场景。Seata是阿里开源的分布式事务中间件,包含XA、TCC、SAGA、AT四种模式。

Head first TCC

try {  callA()} catch (e) {  rollbackA()  exit()}try {  callB()} catch (e) {  rollbackB()  rollbackA()  exit()}

上面的代码无法保证A、B同时成功,或者失败,没有任何地方能够确信目前执行到哪。具体点,就是执行上面代码的机器发生了宕机,怎么知道代码执行到哪一步骤了,是否执行成功了。因为不能确切知道A、B是否执行成功或者回滚成功,所以无法进行补偿重试或者回滚操作。但是,如果有一个平台能够知道当前系统执行状态,比如能确定当前A执行成功,B执行失败,那么就可以调用A、B的回滚操作。通过事务补偿保证A、B要么同时成功,要么同时失败。

通过补偿实现分布式事务保证了最终一致性,是弱一致性。

事务补偿型的分布式事务解决方案有多种,这里只谈TCC。TCC增加协调者记录目前各个子事务(A、B的执行)的状态,由框架统一管理。

相较于传统事务,TCC还增加了try阶段,提前检查所包含的服务能否执行,如检查用户是否有100元下单支付。分布式事务内所包含的所有服务try成功才可以进行confirm,否则进入cancel阶段。

总结下TCC,核心思想就两条:1.事务补偿 2.增加try阶段,try阶段后文会逐步加深印象。

TCC分三个部分

1.尝试(Try):开始执行分布式事务,并锁定相关资源。

解释下锁定资源。比如银行转账,A向B转钱,service A并不会在这个阶段扣A账户上的钱,只会在A账户上增添一个冻结资产的字段,修改冻结资产。所以使用TCC方案的数据库必须提前设计好,增加锁定资源的字段。Try阶段究竟怎么设计取决于业务。

2. 确认(Confirm):如果在执行分布式事务过程中没有发生错误,则提交事务并释放锁定的资源也就是回滚try阶段的操作。

3. 取消(Cancel):如果在执行分布式事务过程中发生了错误,则回滚事务并释放锁定的资源,即回滚try阶段操作。

根据TCC协议,Confirm和Cancel是只返回成功,不会返回失败。如果service机器宕机或者网络等问题导致confirm失败,那么TCC的框架内部会进行重试,最终成功。也就是confirm阶段必须成功,如果失败就不停重试。从这个角度看,TCC属于补偿性事务框架。如果重试很多次仍然失败,比如用户账号突然被冻结,完全不可操作,公司内部会有报警或者定时任务然后查询相关数据库发现这种问题,由人工处理。

问题:为什么不直接向协调者confirm,对于转账业务也就是直接扣A 10块钱,B到账10块钱。如果confirm失败,协调者再向已经confirm过的service发起回滚操作?协调者知道各个service的调用情况,也能保证它们要么都执行成功或者都执行失败。

解释:有类似做法的分布式事务解决方案,比如SAGA。但是直接confirm,之后再回滚,会对用户产生影响,用户可能看到自己的钱先变多了后来又减少变回来了。因此TCC先去try,提前询问各个service是否有足够的资源提交,如果没有,则不进行confirm,如果所有service try都能执行成功,那至少说明每个service业务上是可以confirm的。因此try阶段怎么设计很重要。

示例

TCC具体实现中,业务开发人员需要做什么。银行转账,A->B 10元,并且A、B两个账户的操作由不同微服务操作。

不包含任何分布式事务框架

而在TCC,数据库增加了字段freezed_amount

伪代码

service A

try:  if amount > 10, then freezed_amount -= 10  else return
confirm:  amount -= 10  cancel:  freezed_amount += 10

service B

try:  freezed_amount += 10
confirm:  amount += 10
cancel:  freezed_amount -= 10 

仅为示例,复制Seata官方提供的代码,有很多问题。具体怎么设计try预留资源取决于具体业务。

调用service A、B的服务,分布式事务发起者的伪代码见下文。

TCC接口实现难点

需要先了解seata的流程

http://seata.io/zh-cn/docs/overview/what-is-seata.html

TM:发起分布式事务的service,比如调用A、B的service

RM:执行分支事务的service,实现TCC三个接口的service,比如A、B

TC:seata服务,也就是TCC协调者

TM伪代码:

A.prepare()do somethingB.prepare()do something

TM发起了分布式事务,调用了RM的prepare(try)接口,这样就向TC注册了分支事务。当所有prepare都执行返回成功后,TC调用RM的commit。

RM的接口需要注意:

幂等:TCC协调者可能会重试confirm操作,因此confirm需要幂等

空回滚:分布式事务包含两个分支事务A、B,A.try成功,B.try一直未返回给TC,因此TC发起cancel,向A、B发起cancel指令。A正常cancel,而B之前可能try并未成功,此时cancel B就是空回滚。因此cancel前需要判断RM是否执行了try。

事务悬挂:还是上面的例子。分布式事务已经回滚了B,对TC而言整个分布式事务已经结束。但是这时之前阻塞的TM已经恢复,然后继续执行B的try函数。由于分布式事务已经结束,B的try也就不会被回滚。因此try前需要判断是否执行了cancel。

目前seata已经在框架内部解决了空回滚和事务悬挂问题,查看下使用方法即可。

Seata使用

请参考官方文档。简单来说首先得启动TCC,部署TCC框架。然后调用的TCC客户端分为分布式事务的发起者与被调用方。

不爱看文档的话,喜欢先看代码的话,官方文档提供的可以避免踩坑的信息有,http://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html中的“步骤四:初始化GlobalTransactionScanner”

如果使用本地测试,不想使用Dubbo等,一定要在包含TCC三个接口的interface类上添加@LocalTCC注解,否则会导致businessActionContext为null, @LocalTCC相关坑请百度搜索更多信息。

这里提供一个可以本地测试代码,修改了TCC官方sample(https://github.com/seata/seata-samples/tree/master/tcc/transfer-tcc-sample/src/main/java/io/seata/samples/tcc/transfer)

没有修改官方sample核心代码,只是从Dubbo改成了本地测试local调用,客户端数据库改为了MySQL,需要安装MySQL 8版本

1. https://github.com/ShengyuFang/seata

2. https://github.com/ShengyuFang/seata-local-tcc-sample

使用方法:

1.为TCC服务端,先执行里面包含的SQL脚本,生成相关table,运行ServerApplication.main()

2.先运行TransferProviderStarter.main()创建table,然后运行TransferApplication.main()

重要的事情说三遍! 生产环境下千万不要直接使用sample代码!生产环境下千万不要直接使用sample代码!生产环境下千万不要直接使用sample代码!因为代码有bug,线程不安全, 数据库先读内存再更新有“超卖问题”,用Mysql update ... where ...很容易解决。“超卖”属于其他问题,超出本文范围。

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

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

相关文章

[附源码]Node.js计算机毕业设计房屋租赁管理系统Express

项目运行 环境配置: Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境:最好是Nodejs最新版,我…

web前端Javascript学习之了解JavaScript弹出框

在JavaScript中,可以创建对话框或弹出窗口来与用户进行交互。 JavaScript具有三种不同类型的弹出框:警告框,确认框和提示框。 一、警告框 警告框是最简单的弹出框。它使可以向用户显示一条短消息。还包括“确定”按钮,用户必须…

巧用Github Action 自动推送docker镜像,白piao github服务器资源,还省时又省力

对于个人开发者来说如果不想再自己电脑上搭建CI/DI系统(毕竟吃资源),Github Action是一个不二的选择。 本文我们来通过 Github Action 实现 SpringBoot 项目的自动编译、制作doceker镜像,最后推送到docker hub 仓库。 Github Acti…

亿华通通过上市聆讯:第三季营收降53% 净亏3457万

雷递网 雷建平 12月13日北京亿华通科技股份有限公司(简称:“亿华通”)日前通过聆讯,准备在香港上市。这之前,亿华通是2020年8月在科创板上市,发行价为76.65元,发行17,630,523股,募集…

技术分享 | 测试平台开发-前端开发之Vue.js 框架(一)

Vue.js 是一套用于构建用户界面的渐进式框架,在目前的前端开放中比较流行的前端框架。 Vue 被设计成自底向上的逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或已有项目整合。但是学习 Vue.js 需要一定的 HTML、CSS、和…

09、SpringBoot中集成SSM及其他插件

1、创建spring Boot项目导入如下基础依赖 <!-- 打包方式 jar 包 --> <packaging>jar</packaging><!-- 指定父工程 --> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</art…

[附源码]Node.js计算机毕业设计房屋中介管理信息系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

[附源码]Python计算机毕业设计SSM基于web的图书借阅管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

常规设置Apache服务器实例

常规设置Apache服务器实例 1&#xff0e;设置文档根目录和首页文件的实例 【例1】默认情况下&#xff0c;网站的文档根目录保存在/var/www/html中&#xff0c;如果想把保存网站文档的根目录修改为/home/wwwroot&#xff0c;并且将首页文件修改为myweb.html&#xff0c;那么该如…

CPU一级缓存L1 D-cache\L1 I-cache与二级缓存L2 cache深度分析

CPU缓存&#xff1a;通过优化的的读取机制&#xff0c;可以使CPU读取缓存的命中率非常高&#xff08;大多数CPU可达90%左右&#xff09;&#xff0c; 也就是说CPU下一次要读取的数据90%都在缓存(SRAM)中&#xff1b; 只有大约10%需要从内存&#xff08;DRAM、DDR等&#xff0…

MATLAB抽样定理实验

目录 一、实验目的 二、实验原理 三、实验要求 四、实验内容 1、连续时间信号时域波形及其幅度谱 2、信号进行抽样 3、频谱分析 4、由各抽样信号恢复出连续时间信号&#xff0c;计算并画出误差函数 一、实验目的 1、掌握抽样定理工作原理 2、练习使用Matlab编程进行抽…

非零基础自学Golang 第2章 安装和运行Go 2.5 安装开发工具

非零基础自学Golang 第2章 安装和运行Go 2.5 安装开发工具 互联网有很多可用的开发工具&#xff08;IDE&#xff09;&#xff0c;对于Go开发者来说&#xff0c;选一款最好用的工具&#xff0c;可以更高效地编码和构建项目。 GoLand是一款由JetBrains公司&#xff08;一家技…

【面试题】三面 面试官:运行 npm run xxx 的时候发生了什么?

大厂面试题分享 面试题库 前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 事情是这样的&#xff0c;直接开讲 面试官&#xff1a;npm run xxx的时候&#xff0c;发生了什么&#xff1f;讲的越详细越好。 我&am…

智能家居DIY之智能插座

WiFi智能插座对于新手接触智能家居产品更加友好&#xff0c;不需要额外购买网关设备 很多智能小配件也给我们得生活带来极大的便捷&#xff0c;智能插座就是其中之一&#xff0c;比如外出忘记关空调&#xff0c;可以拿起手机远程关闭。 简单说就是&#xff1a;插座可以连接wi…

深度学习的初学者用哪本书比较好的?

先推荐一本从基本概念和理论入手的深度学习书&#xff1a; 深度学习&#xff1a;从基础到实践&#xff08;上、下册&#xff09; 本书从基本概念和理论入手&#xff0c;通过近千张图和简单的例子由浅入深地讲解深度学习的相关知识&#xff0c;且不涉及复杂的数学内容。 本书分…

交叉梯度函数的MATLAB实现及代码分享01

交叉梯度函数的MATLAB实现及代码分享01 交叉梯度函数可用于反演成像中。作为一个连接不同物性参数的桥梁&#xff0c;交叉梯度函数可以实现不同物性参数的联合反演成像。 文章目录交叉梯度函数的MATLAB实现及代码分享01一、交叉梯度函数的定义二、交叉梯度函数的性质三、模型算…

14:30面试,14:38就出来了 ,问的实在是太...

从外包出来&#xff0c;没想到算法死在另一家厂子&#xff0c;自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到8月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有…

考虑特性分布的储能电站接入的电网多时间尺度源储荷协调调度策略(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

为什么mac电脑识别不出来u盘?macbook识别不了u盘的解决办法

为什么mac电脑识别不出来u盘&#xff1f;关于U盘插入Mac电脑无反应的情况有很多种&#xff0c;是电脑无法识别U盘&#xff1f;电脑上面没有U盘的图标&#xff1f;还是插入后无法对U盘进行写入&#xff1f;针对不同的情况&#xff0c;解决的方法也是不一样的。现在&#xff0c;我…

电脑重装系统一启动就黑屏了该怎么办

相信很多用户都遇到过电脑一开机就黑屏了的问题&#xff0c;对于这个问题很多用户不知道怎么去排查问题&#xff0c;这里就和大家简单聊聊遇到电脑开机黑屏这种情况都有什么原因&#xff0c;又该如何解决吧。下面一起来看看解决方法吧&#xff01; 电脑一启动就黑屏的问题该如何…