微服务13-Seata的四种分布式事务模式
文章目录
- XA模式
- 实现XA模式
- AT模式
- AT模式的脏写问题(对同数据并发写的问题)
- 其他事务不获取全局锁的一个情况(AT模式写隔离的实现)
- 实现AT模式
- TCC模式
- TCC实现
- 我们怎么样去判断是否空回滚和业务悬挂?
- 业务分析
- Saga模式
- 总结
XA模式
XA模式分为两种情况:
提交成功:
提交失败:
具有强一致性seata相当于是在RM上做了一层封装;
XA模式
优点
:
1.事务的强一致性,只要有失败的,TC事务协调者就会发送信息让RM回滚——>满足ACID原则
2.没有代码侵入,常用数据库都支持
缺点
:
1.第一阶段就要锁定数据库资源,但是却不提交,从而导致数据库所占用的资源不能释放(占数据库锁),性能较差
2.依赖关系型数据库实现事务
实现XA模式
步骤:
1.在yaml文件中开启XA代理模式
2.添加@GlobalTransactional注解开启全局事务
AT模式
利用快照来保证事务的一致性,来进行数据回滚;
AT模式是一种最终一致的模式
:因为RM资源管理器执行sql后会直接提交,那么此时如果是数据不一致的情况下,那么说明肯定是软一致,但是在阶段二时,AT模式RM资源管理器会利用快照进行数据回滚,从而保证最终一致;
AT模式直接提交,有利于提高效率
AT模式的脏写问题(对同数据并发写的问题)
脏写问题
:造成数据空转现象
什么是脏写:
简而言之,就是两个事务并发执行,修改同一条数据,我第一个事务修改并且提交之后,释放DB锁资源,第二个事务想要进行回滚,那么就会导致脏写——>前一个事务修改无效
解决
:对事务2造成数据空转现象进行处理
1.事务1先获取DB锁,并且保存快照
——>2.然后执行业务sql,我们在提交事务前获取全局锁(防止一提交事务,释放DB锁后,其他事务立马插入获取DB锁更改sql)
——>3.此时全局锁会记录操作当前数据的事务,让该事务持有全局锁,然后提交事务释放DB锁
——>4.此时其他事务可以争夺DB锁,执行业务sql
——>5.然后和之前一样,它也要获取全局锁,但是全局锁此时已经被事务1拿了,所以它会进行自旋(300ms)
——>6.然后事务1如果此时要根据快照恢复数据,那么就需要DB锁,但是DB锁此时被其他事务拿了
——>7.死锁现象发生
——>8.还好其他事务重试失败后会释放锁资源,因为获取全局锁失败,那么后面的事务提交也进行不了
——>9.事务1再次拿到DB锁,可以进行快照恢复数据了;
其他事务不获取全局锁的一个情况(AT模式写隔离的实现)
利用了CAS的思想 :
实际上是有两份快照的:before-image、after-image
跟cas一样,before是我们要回滚目标的状态,而after是相当于验证的一个状态,如果满足after的内容,就可以设置为before;
如果不一样不满足的话,就会判断不能恢复回滚,那么我们可以记录异常发送警告;
总结:
AT:在第一阶段RM直接提交事务,释放数据库资源,不需要像XA模式那样,还需要将状态返回给TC事务协调者,
还利用了全局锁实现读写分离
:将表执行的事务储存起来,相当于一个标识;
并且**没有代码侵入,seata自动完成回滚和提交——>seata相当于RM资源管理器的一个代理
**
实现AT模式
数据库表中:lock_table:全局锁,undo_log:放的是快照信息
可以再下单途中在业务代码中加上断点的方式查看数据库表中记录的快照信息和AT模式的全局锁信息 他们会在业务结束时自动销毁清理干净
TCC模式
那我们TCC模式是怎么保证一致性?
首先我们想想AT模式,在第一阶段,通过对数据库锁的获取完成事务,事务都是隔离的,所以有人成功有人失败,只有在二阶段完成回滚才能够保证数据的最终一致性,中间还是出现了软状态;
而TCC模式
,为什么就不需要锁了呢?我们AT模式是利用全局锁来保证一致性的——>执行sql后提交前上一道全局锁,那么其他事务的sql就执行不了进行自旋,超时就释放DB锁,而TCC解决
:利用了每个事务都是预留资源进行处理
——> 第一个事务冻结的金额和第二个事务冻结的金额是不一样的,跟其他事务是没有关系的,那么回滚事务也是跟其他事务不影响的,不需要加锁(类似Semaphore)
简而言之就是把事务所用到的资源预留起来 等后面的结果再来判断是扣除还是释放,预留起来后数据库原表中的数据已经扣除了,所以其他的业务请求也不会有影响
TCC模式的关键在于有代码侵入:需要考虑Comfirm成功提交和Cancel数据回滚的编写
优点:1.TCC第一阶段直接提交事务,提交完直接释放数据库资源,AT的话也是直接执行,但是使用了全局锁来保存事务操作的一个状态,保证其他事务争夺不了,XA的话第一阶段就垃圾了,不会提交sql业务,需要把状态给到TC事务协调者进行判断是否回滚还是提交(是一提交或者回滚就是全局那种);
2.无需生成快照与全局锁,依赖的是一个补偿操作,因为事务直接提交的原则,所以其他事务是操作不到自己的,可用于非关系型数据库
TCC实现
具体模式还得根据场景来,比如TCC,就很像Semaphore,一般来说是对一个共享资源进行操作,比如停车场的停车位,库存…,像下单服务就不适合了,因为你每次调用都是一个新的订单;
一个事务是可以有多个模式实现的
我们怎么样去判断是否空回滚和业务悬挂?
利用两者相互判断 根据冻结金额的那张表来判断 在进行try业务前 先查询一下冻结金额的表中的数据是否为空 如果不为空则证明已经执行了CANCEL操作 则需要直接拒绝try的操作,反之在进行cancel业务前,需要根据事务id查询一下冻结金额的表中的数据是否为空 如果为空的话则证明try业务还没做,需要进行空回滚,同时也需要记录数据,new一个新的对象将冻结金额设为0,以及其他数据set进去
业务分析
我们可以在BusinessActionContext中获取里面的参数
事务表:表示事务冻结金额,冻结金额状态发生改变——>表示那部分被锁定
事务id,用户id,冻结金额和状态
业务方便代码的实现
:
@Slf4j
@Service
public class AccountTCCServiceImpl implements AccountTCCService {@Autowiredprivate AccountMapper accountMapper;@Autowiredprivate AccountFreezeMapper accountFreezeMapper;@Override@Transactionalpublic void deduct(String userId, int money) {//0.获取事务idString xid = RootContext.getXID();// 判断是否有冻结记录 有的话直接拒绝执行try业务AccountFreeze Freeze = accountFreezeMapper.selectById(xid);if (Freeze!=null) {//拒绝return;}//1.扣减可用余额accountMapper.deduct(userId, money);//2.记录冻结金额,记录事务状态AccountFreeze accountFreeze = new AccountFreeze();accountFreeze.setUserId(userId);accountFreeze.setFreezeMoney(money);accountFreeze.setState(AccountFreeze.State.TRY);accountFreeze.setXid(xid);accountFreezeMapper.insert(accountFreeze);}@Overridepublic boolean confirm(BusinessActionContext ctx) {//0.获取事务idString xid = ctx.getXid();//1.删除数据int count = accountFreezeMapper.deleteById(xid);return count == 1;}@Overridepublic boolean cancel(BusinessActionContext ctx) {//0.查询冻结记录AccountFreeze accountFreeze = accountFreezeMapper.selectById(ctx.getXid());String userId = (String) ctx.getActionContext("userId");//0.2.判断是否空回滚if (accountFreeze == null){accountFreeze = new AccountFreeze();accountFreeze.setUserId(userId);accountFreeze.setFreezeMoney(0);accountFreeze.setState(AccountFreeze.State.CANCEL);accountFreeze.setXid(ctx.getXid());accountFreezeMapper.insert(accountFreeze);return true;}//0.3 幂等判断if (accountFreeze.getState()==AccountFreeze.State.CANCEL){//已经处理过cancel了 无需重复业务return true;}//1.恢复可用余额accountMapper.refund(accountFreeze.getUserId(),accountFreeze.getFreezeMoney());//2.将冻结金额清零 改状态为cancelaccountFreeze.setFreezeMoney(0);accountFreeze.setState(AccountFreeze.State.CANCEL);int count = accountFreezeMapper.updateById(accountFreeze);return count == 1;}
}
Saga模式
与TCC模式类似,但是TCC第一阶段只是将资源进行冻结,真正的去除还是在第二阶段的,而Saga模式是直接提交本地事务,第二阶段直接操作事务本身:成功则什么都不做,失败则通过编写补偿业务来进行回滚;
与AT相比没有用锁,与TCC比没有冻结资源,性能较好;
失败用自定义的补偿来写;
缺点:
没有保证隔离性,既没有隔离预留资源又没有上锁,容易出现脏写
总结
相关文章:

微服务13-Seata的四种分布式事务模式
文章目录 XA模式实现XA模式 AT模式AT模式的脏写问题(对同数据并发写的问题)其他事务不获取全局锁的一个情况(AT模式写隔离的实现)实现AT模式 TCC模式TCC实现我们怎么样去判断是否空回滚和业务悬挂?业务分析 Saga模式总…...

C结构体内定义结构体,不能直接赋值。
现像: 如下代码: 头文件: typedef struct aBlinkGpioPinOutAbst_{void (*initAsOutput)(void);void (*high)(void);void (*low)(void); }aBlinkGpioPinOutAbst;typedef struct aBlinkGpioAbst_{ #if GPIO_CONFIG_PA0 GPIO_CONFIG_AS_OUTPU…...

PHP遇见错误了看不懂?这些错误提示你必须搞懂
🎬 鸽芷咕:个人主页 🔥 个人专栏:《速学数据结构》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活! 文章目录 一、错误分类二、系统错误:2.1 编译错误2.2 致命错误2.3 警告错误2.4 通知错误 三、用户错误3.1 错…...

微信小程序备案流程操作详解
1、2023年9月1号小程序开始必须备案了,各位小程序商城只需要按流程自主去微信小程序后台操作即可; 2、对未上架的微信小程序,从2023年9月1号开始需先备案才能上架; 3、对存量已上架的小程序,需在2024年3月31号前完成备案即可。逾期未完成备案,平台将按照备案相关规定于…...

【100天精通Python】Day70:Python可视化_绘制不同类型的雷达图,示例+代码
目录 1. 基本雷达图 2. 多组数据的雷达图 3 交互式雷达地图 4 动态雷达图 0 雷达图概述 雷达图(Radar Chart),也被称为蜘蛛图(Spider Chart)或星型图,是一种用于可视化多维数据的图表类型。雷达图通常由…...

KY258 日期累加
KY258 日期累加 int main() {int n 0; //样例个数cin >> n;//for循环处理n个样例for (int i 0; i < n; i){int y, m, d, num;int days[12] { 31,28,31,30,31,30,31,31,30,31,30,31 };//输入年月日 要加的天数cin >> y >> m >> d >>…...

基于CodeFormer实现图片模糊变清晰,去除马赛克等效果
前言 CodeFormer是一种基于AI技术深度学习的人脸复原模型,由南洋理工大学和商汤科技联合研究中心联合开发。该模型通过结合了VQGAN和Transformer等技术,可以通过提供模糊或马赛克图像来生成清晰的原始图像。可以实现老照片修复、照片马赛克修复、黑白照…...
Docker【部署 05】docker使用tensorflow-gpu安装及调用GPU踩坑记录
tensorflow-gpu安装及调用GPU踩坑记录 1.安装tensorflow-gpu2.Docker使用GPU2.1 Could not find cuda drivers2.2 was unable to find libcuda.so DSO2.3 Could not find TensorRT&&Cannot dlopen some GPU libraries2.4 Could not create cudnn handle: CUDNN_STATUS_…...
前后端分离中,前端请求和后端接收请求格式总结
get请求可以携带的参数 1)前端:传统键值对(http:xx?a1&b1) <--> 后端:RequestParam("a") int a , RequestParam("b") int b 2)前端:(http:xx/a/b) <--> 后端:Reque…...

pytorch的基本运算,是不是共享了内存,有没有维度变化
可以把PyTorch简单看成是Python的深度学习第三方库,在PyTorch中定义了适用于深度学习的基本数据结构——张量,以及张量的各类计算。其实也就相当于NumPy中定义的Array和对应的科学计算方法,正是这些基本数据类型和对应的方法函数,…...

Visual Studio 2022新建项目时没有ASP.NET项目
一、Visual Studio 2022新建项目时没有ASP.NET项目 1、打开VS开发工具,选择工具菜单,点击“获取工具和功能” 2、选择“ASP.NET和Web开发”和把其他项目模板(早期版本)勾选上安装即可...
nuiapp项目实战:导航栏动态切换效果实践案例树
测试软件的百忙之中去进行软件开发的工作,开展开发软件的工作事情,也真是繁忙至极点的了。 不到一刻钟的课程内容,个人用了三次去写串联的知识点,然后这是第三次,还是第四次了才完全写出来一个功能的效果。 一刻钟的功…...

【机器学习】集成学习(以随机森林为例)
文章目录 集成学习随机森林随机森林回归填补缺失值实例:随机森林在乳腺癌数据上的调参附录参数 集成学习 集成学习(ensemble learning)是时下非常流行的机器学习算法,它本身不是一个单独的机器学习算法,而是通过在数据…...

主机jvisualvm连接到tomcat服务器查看jvm状态
使用JMX方式连接到tomcat,连接后能够查看前边的部分内容,但是不能查看Visual GC,显示不受此JVM支持, 对了,要显示Visual GC,首先要安装visualvm工具,具体安装方式就是根据自己的jdk版本下载…...
uniapp 自定义tabbar页面不刷新
最近在做自定义tabbar时,每次切换页面都要刷新,页面渲染很慢,需要实现切换页面不刷新问题。 结局思路,原生的tabbar切换页面时就不选新,用switchTab来跳转 1.pages.json中配置tabbar,如下,设置高度为0&am…...

3.1 SQL概述
思维导图: 前言: 前言笔记:第3章 关系数据库标准语言SQL - **SQL的定义**: - 关系数据库的标准和通用语言。 - 功能强大,不仅限于查询。 - 功能覆盖:数据库模式创建、数据插入/修改、数据库安全性与…...

xray安装与bp组合使用-被动扫描
xray安装与bp组合使用-被动扫描 文章目录 xray安装与bp组合使用-被动扫描1 工具官方文档:2 xray官网3 工具使用4 使用指令说明5 此为设置被动扫描6 被动扫描-启动成功7 启动bp7.1 设置bp的上层代理7.2 添加上层代理7777 --》指向的是xray7.3 上层代理设置好后&#…...
Java 中Maven 和 ANT
Java 中Maven 和 ANT Maven 和 Ant 都是用于构建和管理Java项目的工具,但它们在设计和功能上有一些重要的区别。以下是关于 Maven 和 Ant 的区别、优缺点以及它们的作用,以及示例说明: Maven: 设计理念: Maven 是基于…...
Flutter通过Pigeon插件与Android同步异步交互
Flutter 调用原生(Android)方法以及数据传输_flutter调用原生sdk_TDSSS的博客-CSDN博客 https://www.cnblogs.com/baiqiantao/p/16340272.html 可以同时参考这两篇文章...
GTW验厂是什么?GTW验厂评级分类
【GTW验厂是什么?GTW验厂评级分类】 GTW验厂是什么? 全称叫GreenToWear。是为了集合所有环境和产品健康方面的要求,Inditex集团开发的可持续发展准则(简称GTW)此准则适用于Inditex集 及其供应链中所包含的湿加工厂&…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...