分布式事务解决方案详解

news2024/11/27 7:30:00

分布式事务

分布式协议

  • XA规范
    XA(eXtended Architecture)标准是X/Open 组织针对分布式事务(DTP)处理的规范,它描述了全局事务管理器和本地资源管理器之间的接口,允许多个资源在同一分布式事务中访问。DTP 模型中包含一个全局事务管理器(TM,Transaction Manager)和多个资源管理器(RM,Resource Manager)。全局事务管理器负责管理全局事务状态与参与的资源,协同资源一起提交或回滚;资源管理器则负责具体的资源操作。
    请添加图片描述
    AP定义事务边界以及那些组成事务的特定于应用程序的操作

分布式事务方案

2PC(强一致性)

2PC即两阶段提交协议(Two Phase Commit),是对XA规范的实现,从字面意思理解就是将提交分为两个阶段:

  • 准备阶段
    TM通知各个RM准备提交它们的事务分支,如果RM本地事务执行成功,则返回成功;如果RM的本地事务执行失败,则返回失败。
  • 提交阶段
    如果TM收到所有分支事务返回成功的消息,则向每个RM发送提交消息;否则发送回滚消息。RM根据TM的指令执行提交或者回滚本地事务操作,释放本地事务处理过程所用的所有资源。

以创建订单业务场景为例分析2PC存在的问题

  1. 锁资源无法释放
    当订单服务操作订单库和调用库存服务后,在准备阶段执行完成后,TM宕机了,此时数据库资源被占用,导致RM一直阻塞,无法释放锁资源
  2. 数据不一致
    在提交阶段,TM给所有RM发送提交请求,如果某些RM由于网络抖动或者请求过程中协调者发生故障,只有部分RM收到了commit请求,接收到commit请求的RM会正常提交分支事务,没有收到commit请求的RM则无法执行事务提交操作,最后导致数据不一致

JTA/XA规范实现
以MySQL为例(MySQL实现了XA规范),模拟两个分支事务组成的分布式事务,伪代码:

  1. 创建两个资源管理器操作接口,分别代表两个分支事务,他们都拥有各自的资源。具体为XAConnection和XAResource。
  2. AP向TM请求创建一个分布式事务表示开始事务,并得到全局事务id。
  3. 分别执行两个分支事务
  4. 准备阶段:TM通过XAResource.prepare()询问两个分支事务,是否可以提交
  5. 提交阶段:如果两个分支事务的prepare()都返回0(成功)则通知各个RM提交事务,否则回滚。

seata AT模式
在这里插入图片描述

TCC(补偿事务/柔性事务)

TCC即Try-Confirm-Cancel

  1. Try:完成所有业务检查,预留必须的业务资源。注意判断:
    a.幂等判断:通过查询日志记录,判断本次分布式事务Try逻辑是否已经有执行记录
    b.悬挂处理:通过查询日志记录,判断本次分布式事务Confirm或者Concel是否又执行记录
  2. Confirm:真正执行的业务逻辑,不做任何业务处理,只是用Try阶段预留的资源。因此,Try能执行成功则Confirm必须能成功。注意Confirm操作的幂等判断
  3. Cancel:释放Try阶段预留的业务资源。同样Cancel操作也需要幂等判断
    空回滚:如果Try操作没有执行,则Cancel操作也不能执行。

TCC分布式事务流程:

在这里插入图片描述

  1. 主业务服务开启本地事务
  2. 主业务流程获取分布式事务唯一id
  3. 主业务服务发起所有从业务服务的Try调用
  4. 当所有从业务服务的Try接口调用成功,主业务服务提交本地事务;若有失败,则本地事务回滚。
  5. 若主业务服务提交本地事务,则TCC模型分别调用所有从业务服务的Confirm接口;若主业务服务回滚本地事务,则调用所有从业务服务的Cancel接口

TCC开源框架

  • Tcc-Transaction
  • Hmily
  • Seata TCC

TCC demo

以转账为例,设计一个转账接口,假设A账户转账10元给B账户:

  • A账户接口伪代码
try:
	判断A账户余额是否大于10
	减少10元
	调用B账户增余额接口
ConfirmCancel:
	增加10
  • B账户接口伪代码
try:
	增加10ConfirmCancel:
	减少10

咋一看似乎逻辑很严谨没有什么问题,但是这里有很多的问题:
1.A账户Try操作没有做幂等判断和悬空判断
2.A账户Cancel操作没有幂等判断和空回滚处理
3.B账户Try操作增加10元,放在Confirm操作处理更简单,并且加上Confirm幂等处理
4.B账户Cancel操作为空

较为合理的伪代码:

  • A账户接口伪代码
try:
	幂等判断(判断Try操作本次事务是否已经执行)
	悬挂处理(判断本次事务的Confirm或者Cancel操作是否已经执行过,如已经执行过就不能执行Try操作)
	判断A账户余额是否大于10
	减少10元
	调用B账户增余额接口
Confirm:
	空
Cancel:
	幂等校验
	判断Try操作是否执行过,如没有执行就不允许Cancel操作执行
	增加10
  • B账户接口伪代码
try:
	空
Confirm:
	幂等校验
	增加10Cancel:
	空

小结

允许空回滚:由于网络丢包导致Try操作失败,必会触发Cancel操作,此时Cancel必须识别出这是空回滚,返回成功。
防悬挂:由于网络堵塞丢包,Try操作超时,此时分布式事务回滚触发Cancel操作,故出现Cancel比Try操作先执行。
幂等控制:Try/Confirm/Cancel都必须做幂等判断,防止重复执行。

可靠消息

本地消息表

请添加图片描述

  • 用户注册
    用户发送注册请求,user_service会将用户注册和赠送优惠券作为本地事务同时入库,保证原子性和一致性
  • 定时任务
    定时任务扫描本地消息日志表,将优惠券消息发送到mq,并在消息中间返回成功后删除本地日志表,否则等到下一次重试。
  • 消息消费
    优惠券服务监听mq消息,在接收到消息并处理成功后,使用mq的应答机制给mq发送ACK确认。此外定要保证消息消费的幂等性。

Rocketmq事务消息最终一致性

RocketMq事务消息
1.生产者将半消息发送个Rocketmq服务
2.Rocketmq服务收到半消息后,给生产者响应半消息发送成功;但此时的半消息只是保存起来不会被消费者消费
3.生产者收到成功后,执行本地事务
4.生产者根据本地事务执行结果向Rocketmq提交二次确认结果(提交或回滚)

  • 提交:本地事务执行成功,提交二次确认结果,此时Rocketmq服务将半事务消息的"暂不能投递"状态改为"可投递"状态,并投递给消费者。
  • 回滚:本地事务执行失败,回滚二次确认结果,将半事务消息改为不投递状态。

5.Rocketmq自动执行回查事务状态
6.生产者收到回查消息后,去检查本地事务是否执行成功
7.再次提交二次确认结果,参照4.

最大努力通知

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

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

相关文章

Linux——内存和DMA(二)

目录 六、动态内存实例 七、 I/0内存 八、DMA原理及映射 8.1 DMA 工作原理 8.2 DMA映射 1.一致性DMA映射 2. 流式DMA映射 3,分散/聚集映射 4.DMA池 5,回弹缓冲区 九、 DMA统一编程接口 十、习题 书接上回: http://t.csdn.cn/n35…

Redis(二)——Redis持久化与主从架构详解

Redis持久化与主从架构详解 Redis的持久化RDB快照(snapshot)(redis默认持久化方式)bgsave的写时复制(COW)机制save与bgsave对比 AOF(append-only file)配置 Redis 多久才将数据 fsync 到磁盘一次AOF重写 如…

网站创建百度百科词条的方法是什么?

百度百科是一个十分全面的在线百科全书,如果您是某个企业、品牌,或是某个行业或领域的专家,想要在百度百科上为自己的网站创造更多曝光率和权威性,那么在百度百科上创建词条就是一项非常有效的方法。这里需要注意的是创建网站类的…

一、OkHttp_网络请求流程

前言: 一直以来总想对android常用的某个第三方库深入研究一下,每次看完源码之后总是经常的忘记。 为了方便对三方库快速阅读,特此以写文章方式记述。 就从OKHttp开始吧。 再阅读源码之前,要明确 OKHttp是用来做什么的?…

交互原型图设计必备软件,这5款太赞了

如果你是UI/UX设计师,你肯定会在工作中涉及到交互原型图的设计。 在设计交互原型图时,我们通常需要找到一些适合自己的交互原型图设计软件来制作高质量的交互原型图。 与您分享5款易于使用的交互原型图设计软件 1.即时设计 即时设计是国内UI/UX设计师…

用代码点亮儿童节烟花游乐园

文章目录 概述代码烟花效果爆炸效果 结果 概述 尊敬的读者朋友们,六一儿童节到了!这是一个属于孩子们的节日,为了庆祝这个特殊的日子,我们将以计算机代码为媒介,打造一个虚拟的烟花游乐园,让我们一起点亮这…

K8s in Action 阅读笔记——【12】Securing the Kubernetes API server

K8s in Action 阅读笔记——【12】Securing the Kubernetes API server 12.1 Understanding authentication 在上一章中,我们提到API服务器可以配置一个或多个认证插件(授权插件也是同样的情况)。当API服务器接收到一个请求时,它…

【LeetCode热题100】打卡第15天:搜索旋转排序数组在排序数组中查找元素的第一个和最后一个位置

文章目录 【LeetCode热题100】打卡第15天:搜索旋转排序数组&在排序数组中查找元素的第一个和最后一个位置⛅前言 搜索旋转排序数组🔒题目🔑题解 在排序数组中查找元素的第一个和最后一个位置🔒题目 【LeetCode热题100】打卡第…

企业为什么要统一身份认证管理?

身份认证管理(Identity and Access Management,IAM)是一套用来控制用户获取网络系统或应用访问权限的技术与流程。主要包括: 1. 身份管理:创建、删除和维护用户账号,管理用户关键信息如姓名、电子邮件等。这是进行访问控制的基础。 2. 认证管…

Spring Boot 统一功能处理

✏️作者:银河罐头 📋系列专栏:JavaEE 🌲“种一棵树最好的时间是十年前,其次是现在” 目录 ⽤户登录权限效验Spring Boot 拦截器自定义拦截器将自定义拦截器加入到系统配置 拦截器实现原理 统一异常处理创建一个异常处…

金融投资心得(个人领悟篇)

金融投资心得 前言金融还是要参与的如何参与金融始终相信中国经济把控风险选股技巧不赚最后一块"铜板"多学习,学会筛选有用消息 其它思考推荐学习我的投资 前言 本人从2015年开始接触金融,不知不觉跟金融已经打了8年交道了,一路走…

基于STM32的智能饮水机系统设计

一、项目背景 随着智能化的迅速发展,人们对于生活中的各类设备也越来越有智能化的需求,其中智能饮水机是一种比较常见的设备。智能饮水机不仅可以提供饮用水,还可以通过智能化的技术满足人们对于水质、水温、出水量等方面的需求。因此&#…

深入浅出:单链表的实现和应用

🌱博客主页:青竹雾色间. 😘博客制作不易欢迎各位👍点赞⭐收藏➕关注 ✨人生如寄,多忧何为 ✨ 目录 前言 单链表的基本概念 节点 头节点 尾节点 单链表的基本操作 创建单链表 头插法: 尾插法&#…

OpenGL蓝宝书第九章学习笔记:片段着色器和帧缓存

前言 本篇在讲什么 OpenGL蓝宝书第九章学习笔记之片段着色器和帧缓存 本篇适合什么 适合初学OpenGL的小白 本篇需要什么 对C语法有简单认知 对OpenGL有简单认知 最好是有OpenGL超级宝典蓝宝书 依赖Visual Studio编辑器 本篇的特色 具有全流程的图文教学 重实践&am…

Node服务器 - koa框架

1 koa的基本使用 2 koa的参数解析 3 koa响应和错误 4 koa静态服务器 5 koa的源码解析 6 和express对比 koa的基本使用过程 const Koa require(koa)// 创建app对象 const app new Koa()// 注册中间件(middleware) // koa的中间件有两个参数: ctx/next app.use((ctx, next…

Apple Vision Pro:空间计算的未来已来,你准备好了吗?

“ 正如iPhone带我们进入移动计算时代,Apple Vision Pro将带我们进入空间计算时代。” 我虽然没有亲身体验,但观看了许多国内外第一批体验者的体验分享,看得出来,这些体验者都十分兴奋,根据他们的描述,我…

Mac安装zookeeper

文章目录 1.下载zookeeper安装包2.解压安装包3.修改配置文件4.启动服务端5.启动客户端 1.下载zookeeper安装包 https://archive.apache.org/dist/zookeeper/ 选择需要的版本下载 下载的时候要注意下载已经编译好的二进制版本 2.解压安装包 将下载的安装包解压到你想要的位…

基于Faster RCNN时间钢铁表面的缺陷检测

目标检测在许多行业中都有许多实际应用。大多数时候,在工业环境中,物体检测目标很小。因此,有效地训练目标检测模型变得非常困难。其中一个问题是钢材表面缺陷检测。即使使用深度学习,也很难高精度地解决问题。在本文中,我们将使用 PyTorch 库训练 Faster RCNN 对象检测模…

【3DsMAX】从零开始建房(5)

目录 1. 制作护栏 2. 制作梯子 3. 制作二层窗户 1. 制作护栏 选中顶部三条边线 点击“利用所选内容创建图形” 选择线性 此时我们就成功的创建了一个二维样条线 选中样条线上其中的一个点,移动点使线条缩短 缩小一点 渲染 同样的方法再制作一根 新建一个圆柱体 …

浅谈Spring Cloud OpenFeign

OpenFeign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。 Spring Cloud OpenFe…