分布式之分布式事务详解

分布式事务与实战运用

什么是分布式事务?

业务场景:用户A转账100元给用户B,这个业务比较简单,具体的步骤:
1、用户A的账户先扣除100元
2、再把用户B的账户加100元

image.png

如果在同一个数据库中进行,事务可以保证这两步操作,要么同时成功,要么同时不成功。这样就保证了转账的数据一致性。
但是在微服务架构中,因为各个服务都是独立的模块,都是远程调用,都没法在同一个事务中,都会遇到分布式事务问题。

RocketMQ的解决方案

image.png

RocketMQ采用两阶段提交,把扣款业务和加钱业务异步化,在A系统扣款成功后,发送“扣款成功消息”到消息中间件;B系统中加钱业务订阅“扣款成功消息”,再对用户进行加钱。

具体的处理方案

image.png

  1. 生产者发送半消息(half message)到RocketMQ服务器

  2. RocketMQ服务器向生产者返回半消息的提交结果

    image.png

  3. 生产者执行本地的事务

    image.png

    image.png1)这里如果是标记为可提交状态(commit),消费者监听主题即可立马消费(TransactionTopic主题),消费者进行事务处理,提交。

    2)如果这里标记为回滚,那么消费者就看不到这条消息,整个事务都是回滚的

    image.png

    3)当然本地事务中还有一种情况,那就是没执行完,这个时候,可以提交UNKNOW,交给事务回查机制。 如果是事务回查中,生产者本地事务执行成功了,则提交commit,消费者监听主题即可立马消费,消费者进行事务处理,提交。 如果这里标记为回滚,那么消费者就看不到这条消息,整个事务都是回滚的。 当然本地事务中还有一种情况,那就是还没执行完,这个时候还是可以继续提交UNKNOW,交给事务回查机制(过段时间继续进入事务回查)。

image.png

RocketMQ分布式事务方案中的异常处理

事务回查失败的处理机制

在生产者有可能是要进行定时的事务回查的,所以在这个过程中有可能生产者宕机导致这条分布式事务消息不能正常进行。那么在RocketMQ中的生产者分组就会发挥作用

image.png

也就是如果在进行分布式事务回查中(RocketMQ去调用生产者客户端)某一台生产者宕机了,这个时候只要还有一台分组名相同的生产者在运行,那么就可以帮助之前宕机的生产者完成事务回查。

image.png

消费者失败补偿机制

虽然在消费者采用最大可能性的方案(重试的机制)确保这条消息能够执行成功,从而确保消费者事务的确保执行。但是还是有可能会发生消费者无法执行事务的情况,这个时候就必须要使用事务补偿方案。

业务场景:用户A转账100元给用户B,这个业务比较简单,具体的步骤:
1、用户A的账户先扣除100元----生产者成功执行了
2、再把用户B的账户加100元----消费者一直加100元失败。

那么就需要去通知生产者把之前扣除100元的操作进行补偿回滚操作。

image.png

image.png

image.png

image.png

RocketMQ的实战运用

image.png

问题分析

分布式系统宕机问题

整个系统是分布式部署,有订单系统、商品系统、会员系统。三个系统通过RPC调用完成整个下单流程。RPC调用会导致下单中各系统耦合在一起,假如会员系统宕机,会导致下单流程的不可用。

如何异步解耦:

利用RocketMQ,订单系统在下单后,作为生产者把“下单消息”写入MQ,商品系统与会员系统作为消费者消费MQ中的“下单消息”。这样可以达到异步解耦的目的,只要订单系统正常,对于用户来说下单业务都可以正常进行。

数据完整性问题

用户提交订单后,扣减库存成功、扣减优惠券成功,但是在确认订单操作失败(比如:支付失败),那么就需要对库存、优惠券进行回退。

如何保证数据的完整性?前面讲到的利用分布式事物消息确保要么都成功,要么都失败。

消息重复消费的幂等性处理

对于消息接收端的情况,幂等的含义是采用同样的输入多次调用处理函数,得到同样的结果。例如,一个SQL操作

update stat_table set count= 10 where id =1

这个操作多次执行,id等于1的记录中的 count字段的值都为10,这个操作就是幂等的,我们不用担心这个操作被重复。

再来看另外一个SQL操作

update stat_table set count= count +1 where id= 1;

这样的SQL操作就不是幂等的,一旦重复,结果就会产生变化。

去重表:

利用数据库表单的特性来实现幂等,常用的一个思路是在表上构建唯一性索引,保证某一类数据一旦执行完毕,后续同样的请求不再重复处理了(利用一张日志表来记录已经处理成功的消息的ID,如果新到的消息ID已经在日志表中,那么就不再处理这条消息。)

以电商平台为例子,电商平台上的订单id就是最适合的token。当用户下单时,会经历多个环节,比如生成订单,减库存,减优惠券等等。每一个环节执行时都先检测一下该订单id是否已经执行过这一步骤,对未执行的请求,执行操作并缓存结果,而对已经执行过的id,则直接返回之前的执行结果,不做任何操作。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言之Linux内核回调函数写法(八十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

论文阅读,Accelerating the Lattice Boltzmann Method(五)

目录 一、Article:文献出处(方便再次搜索) (1)作者 (2)文献题目 (3)文献时间 (4)引用 二、Data:文献数据(总结归纳,方便理解&am…

Nginx的反向代理

Nginx的反向代理 location ^~ /aaa {proxy_pass http://192.168.15.78/; } 1. 跨域 2.Nginx 代理服务器缓存 3.Nginx 负载均衡 4. 动静分离 Nginx的跨域 跨源资源共享 (CORS) 是一种机制,它使用额外的 HTTP 标头让用户代理获得访问来自不同来域的服务器上选定资…

LongAdder 和 AtomicLong

有幸看到一篇关于这个讲解 2个类的讲解,自己也归纳总结一下。 一、解析 看源码底层会发现实现机制不一样,当然这个也是必须的 LongAdder 点进去之后会发现,CAS 它是一个CAS的实现类。至于Cell类JVM提供的内置函数 官方说法是:…

Python版【植物大战僵尸 +源码】

文章目录 写在前面:功能实现环境要求怎么玩个性化定义项目演示:源码分享Map地图:Menubar.py主菜单 主函数:项目开源地址 写在前面: 今天给大家推荐一个Gtihub开源项目:PythonPlantsVsZombies,翻译成中就是…

小程序开发调试指南

调试指南 一、Vconsole 一些线上问题需要在真机中进行调试或日志输出,为方便查看前端日志的输出,App 端提供了调试模式, 打开调试模式后面板界面中会显示 vConsole 按钮,点击后可打开手机端 vConsole界面查看日志输出。 1.如何开启 点击小…

JumpServer 堡垒主机

JumpServer 堡垒机帮助企业以更安全的方式管控和登陆各种类型的资产 SSH:Linux/Unix/网络设备等Windows:Web方式连接/原生RDP连接数据库:MySQL、Oracle、SQLServer、PostgreSQL等Kubernetes:连接到K8s集群中的PodsWeb站点&#x…

复现黄金票据

一、搭建环境 搭建域环境可以点击这个查看步骤 在这里面monowall的配置查看 二、实验步骤 拿到域名 拿到SID 使用mimikatz拿到krbtgt用户的哈希 删除票据 也可以使用mimikatz.exe删除票据,命令是kerberos::purge 伪造票据 拿到域控 伪造成功

物联网实战--入门篇之(六)嵌入式-WIFI驱动(ESP8266)

目录 一、WIFI简介 二、基础网络知识 三、思路讲解 四、代码分析 4.1 状态机制 4.2 客户端连接 4.3 应用数据接收处理 4.4 数据发送 4.5 主函数调用 4.6 网络连接ID分配 五、总结 一、WIFI简介 WIFI在我们生活中太常见了,手机电脑都可以用WiFi连接路由器进行上…

MySQL核心命令详解与实战,一文掌握MySQL使用

文章目录 文章简介演示库表创建数据库表选择数据库删除数据库创建表删除表向表中插入数据更新数据删除数据查询数据WHERE 操作符聚合函数LIKE 子句分组 GROUP BY HAVINGORDER BY(排序) 语句LIMIT 操作符 分页查询多表查询-联合查询 UNION 操作符多表查询-连接的使用-JOIN语句编…

从0到1手把手撸码搭建后台管理系统

从0到1手把手撸码搭建后台管理系统 第一章:系统介绍开发目的与过程 要使用 Vue3 搭建后台,你可以按照以下步骤进行: 安装 Vue3:使用包管理工具(如 npm 或 yarn)安装 Vue3。选择构建工具:选择一个适合的构…

Spring之循环依赖

什么是循环依赖? 依赖的相互引用,如下列的这种形式 Component public class A {Autowiredprivate B b;}Component public class B {Autowiredprivate A a; } Spring是如何解决循环依赖的 Spring是通过三级缓存来解决循环依赖 singletonObjects : 单例bean,已经实例化,完成…

非周期连续函数的傅里叶变换

首先 我们把一个非周期信号扩展成一个周期信号 然后用傅里叶级数展开 也可以得到对应的级数系数 利用周期趋向于无穷大 可以把傅里叶级数展开就变成了一个积分 而神奇的是积分里其实还有一个积分 这样我们就得到了傅里叶变换对 我们把里面的积分成为函数的傅里叶变换 把外面…

C语言交换二进制位的奇数偶数位

基本思路 我们要先把想要交换的数的二进制位给写出来假如交换13的二进制位,13的二进制位是 0000 0000 0000 0000 0000 0000 0000 1101然后写出偶数位的二进制数(偶数位是1的) 1010 1010 1010 1010 1010 1010 1010 1010然后写出奇数位的二进…

Mac通过Idea启动Tomcat时出现Cannot run program xxx/catalina.sh 错误

问题描述 Mac通过Idea启动Tomcat时出现Cannot run program xxx/catalina.sh错误,详细如下: Error running Tomcat9 Cannot run program "/Users/xxx/Desktop/work/devtools/apache-tomcat-9.0.19/bin/catalina.sh" (in directory "/U…

算法设计课第一周(排序算法的效率分析)

实验1 排序算法的效率分析 一、【实验目的】 (1)复习排序算法的实现过程; (2)设计平均与最坏情况下时间复杂度的数据环境并理解相关含义; (3)初步了解算法时间复杂度的分析方法。…

FlashFace:一种高保真身份保存的人类形象个性化方法

FlashFace技术是由香港大学、阿里巴巴集团、蚂蚁集团共同研发的一项实用工具,用户可以通过提供一张或几张参考面部图像和文本提示,就可以轻松地即时个性化自己的相片。 与现有的人像定制方法相比,FlashFace方法具有更高保真度的身份保留xi性…

【spring】Spring Cloud Alibaba版本发布说明

Spring Cloud Alibaba版本发布说明 由于 Spring Boot 3.0,Spring Boot 2.7~2.4 和 2.4 以下版本之间变化较大,目前企业级客户老项目相关 Spring Boot 版本仍停留在 Spring Boot 2.4 以下,为了同时满足存量用户和新用户不同需求,社…

Vue 组件化编程

Vue 组件化编程 非单文件组件 定义组件 使用Vue.extend(options)创建 不要写eldata要写成函数,避免组件被复用时,数据存在引用关系 注册组件 局部注册:new Vue()的时候,options传入components全局注册:V…

Linux 个人笔记之三剑客 grep sed awk

文章目录 零、预一、grep 文本过滤工具基础篇实战篇 二、sed 字符流编辑器基础篇实战篇 三、awk 文本处理工具基础篇实战篇 四、附xargsuniq & sort基础篇实战篇 cut 零、预 bash 的命令行展开 {} $ echo file_{1..4} file_1 file_2 file_3 file_4$ echo file_{a..d} file_…