微服务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比没有冻结资源,性能较好;

失败用自定义的补偿来写;

缺点:

没有保证隔离性,既没有隔离预留资源又没有上锁,容易出现脏写

在这里插入图片描述

总结

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[elasticsearch]使用postman来查询数据

最近需要debug程序,debug的时候需要查找elasticsearch里面的数据是否正确。 第一步建立一个post请求,并按照图下的方式填上ur和参数: 发送post请求,url为: http://ip:port/index_name/_search我这里查询的是title字…

k8s使用

一、Kubernetes好处 ​ kubernetes,是一个全新的基于容器技术的分布式架构领先方案,是谷歌严格保密十几年的秘密武器----Borg系统的一个开源版本,于2014年9月发布第一个版本,2015年7月发布第一个正式版本。 ​ kubernetes的本质…

常见的作物模型有哪些?DSSAT模型、APSIM模型、WOFOST模型与PCSE模型等应用

目录 ①最新DSSAT作物模型建模方法及应用 ②基于Python语言快速批量运行DSSAT模型及交叉融合、扩展应用 ③R语言与作物模型(以DSSAT模型为例)融合应用 ④WOFOST模型与PCSE模型应用 ⑤基于R语言APSIM模型进阶应用与参数优化、批量模拟 ⑥遥感数据与…

网工配置命令基础总结(2)----VRRP配置

目录 1.配置VRRP主备备份 2.配置VRRP负载分担 3.配置VRRP域BFD联动实现快速切换 VRRP 虚拟路由冗余协议 VRRP(Virtual Router Redundancy Protocol)通过把几台路由设备联合组成一台虚拟的路由设备,将虚拟网关设备的 IP 地址作为用户的默认…

内部类概述

一、内部类 1.内部类概述 2.内部类的四种实现形式 1.成员内部类 public class Outer {private int age99;public static String a;//成员内部类public class Inner{private int age88;private String name; // public static String school; //jdk 16开始才支持定义静态…

基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持自定义业务表单流程(一)

原先不支持自定义业务表单的流程流转,因为这样对很多用户就更加方便,流程还是用现有的流程,但表单可以自己单独设计,满足各种不同的业务需求。 1、增加一个接口传入当前设计的流程应用类型 /*** 获取流程分类详细信息* param cod…

如何报考产品总监认证(UCPD)?

从产品经理到产品总监,是我们职业生涯中锦鲤化龙的一次历程。中、高级管理人员所需要的知识和能力常常会泾渭分明,甚至大相迳庭。所以,当我们走向高级管理岗位前,尤其是有机会应聘大厂总监岗位时,我们需要一张产品总监…

springcloud----检索中间件 ElasticSearch 分布式场景的运用

如果对es的基础知识有不了解的可以看 es看这个文章就会使用了 1.分布式集群场景下的使用 单机的elasticsearch做数据存储,必然面临两个问题:海量数据存储问题、单点故障问题。 海量数据存储问题:将索引库从逻辑上拆分为N个分片&#xff08…

17.(开发工具篇Gitlab)如何在Gitlab配置ssh key

前言: Git是分布式的代码管理工具,远程的代码管理是基于SSH的,所以要使用远程的Git则需要SSH的配置 一、git 配置 (1)打开 git 命令窗口 (2)配置用户名(填自己的姓名) git config --global user.name “chenbc” (3)配置用户邮箱(填自己的邮箱) git config …

【计算机网络】——前言计算机网络发展的历程概述

主页点击直达:个人主页 我的小仓库:代码仓库 C语言偷着笑:C语言专栏 数据结构挨打小记:初阶数据结构专栏 Linux被操作记:Linux专栏 LeetCode刷题掉发记:LeetCode刷题 算法:算法专栏 C头…

HTTP 响应头 X-Frame-Options

简介 X-Frame-Options HTTP 响应头用来给浏览器一个指示。该指示的作用为&#xff1a;是否允许页面在 <frame>, </iframe> 或者 <object> 中展现。 网站可以使用此功能&#xff0c;来确保自己网站的内容没有被嵌套到别人的网站中去&#xff0c;也从而避免了…

spring6-事务

文章目录 1、JdbcTemplate1.1、简介1.2、准备工作1.3、实现CURD①装配 JdbcTemplate②测试增删改功能③查询数据返回对象④查询数据返回list集合⑤查询返回单个的值 2、声明式事务概念2.1、事务基本概念①什么是事务②事务的特性 2.2、编程式事务2.3、声明式事务 3、基于注解的…

PostMan环境变量、全局变量、动态参数使用

一、环境准备 postmanmoco [{"description": "登录认证","request": {"uri": "/login","method": "post","forms": {"user": "admin","password": "a123…

pycharm远程调试运行程序出现No such file or directory:解决办法

太离谱了&#xff01;&#xff01;&#xff01;&#xff01; 首先还是配置这里 然后重点来了&#xff0c;root path这里填上代码文件夹路径 然后mapping这里就不要再加了&#xff01;&#xff01;&#xff01;因为这个会和上面的root path拼在一起&#xff01;&#xff01;&am…

基于nodejs+vue大学食堂订餐系统

模块包括主界面&#xff0c;首页、个人中心、管理员管理、用户管理、菜品管理、论坛管理、公告管理、基础数据管理、目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1nodejs简介 4 2.2 express框…

uniapp封装loading 的动画动态加载

实现效果 html代码 <view class"loadBox" v-if"loading"><img :src"logo" class"logo"> </view> css代码 .loadBox {width: 180rpx;min-height: 180rpx;border-radius: 50%;display: flex;align-items: center;j…

Java 解析 cURL(bash) 命令

解析 cURL&#xff08;bash&#xff09; 命令 1. 主要用于解析从浏览器复制来的 cURL(bash)2. 废话不多说&#xff0c;都在&#x1f37b;代码里了。参考资料 1. 主要用于解析从浏览器复制来的 cURL(bash) curl https://eva2.csdn.net/v3/06981375190026432f77c01bfca33e32/lts/…

【yolov5】改进系列——特征图可视化(V7.0 的一个小bug)

文章目录 前言一、特征图可视化1.1 V7.0的小bug 二、可视化指定层三、合并通道可视化总结 前言 对于特征图可视化感兴趣可以参考我的另一篇记录&#xff1a;六行代码实现&#xff1a;特征图提取与特征图可视化&#xff0c;可以实现分类网络的特征图可视化 最近忙论文&#xf…

Docker开启远程访问+idea配置docker+dockerfile发布java项目

一、docker开启远程访问 1.编辑docker服务文件 vim /usr/lib/systemd/system/docker.servicedocker.service原文件如下&#xff1a; [Unit] DescriptionDocker Application Container Engine Documentationhttps://docs.docker.com Afternetwork-online.target docker.socke…

natapp内网穿透-将本地运行的程序/服务器通过公网IP供其它人访问

文章目录 1.几个基本概念1.1 局域网1.2 内网1.3 内网穿透1.4 Natapp 2.搭建内网穿透环境3.本地服务测试 1.几个基本概念 1.1 局域网 LAN&#xff08;Local Area Network&#xff0c;局域网&#xff09;是一个可连接住宅&#xff0c;学校&#xff0c;实验室&#xff0c;大学校…