Apache Seata 新版本集成了 RocketMQ 事务消息

大家好,我是君哥。

Apache Seata 是一款高性能、简单易用的分布式事务中间件,它包含 AT、TCC、SAGA 和 XA 四种模式。

在最近发布的新版本中,Apache Seata 引入了 RocketMQ 中间件,并且跟 RocketMQ 的事务消息配合使用。今天我们来聊一聊这个话题。

Seata 两阶段提交

Seata 的分布式事务解决方案使用两阶段提交,以最流行的 TCC 模式为例,Seata 中设计了 3 个主要的角色:

  • TM:管理全局事务,包括开启全局事务,提交/回滚全局事务;

  • RM:管理分支事务;

  • TC: 事务协调器,管理全局事务和分支事务的状态。

下图是一个电商场景的分布式事务场景,包括订单、库存和账户三个服务。TM 开启全局事务后,在第一阶段,订单服务、库存服务和账户服务分别作为一个 RM 向 TC 注册分支事务,并且向 TC 上报分支事务执行状态。如果三个分支事务都执行成功,TM 会给 TC 发送 commit 执行,否则发送 rollback 指令。在第二阶段,TC 会根据 TM 的指令,决定分支事务 commit 或者 rollback。

RocketMQ 事务消息

作为分布式事务的解决方案,RocketMQ 的事务消息也可以供我们选择。RocketMQ 的事务消息,主要是保证了本地方法执行和消息发送在一个分布式事务中,要不全部成功,要不全部失败。见下图:

这里给出一个账户服务和库存服务在一个分布式事务中的例子,本地方法执行扣减账户金额,RocketMQ 消费者消费账户服务发送的消息后执行扣减库存。RocketMQ 通过发送 half 消息来实现,下面详细说明一下:

  1. 账户服务向 Broker 发送一条 half 消息;

  2. half 消息发送成功后,账户服务执行本地事务;

  3. 如果账户服务执行本地事务成功,则向 Broker 发送 commit 请求,否则发送 rollback 请求;

  4. 如果 Broker 收到的是 rollback 请求,则删除保存的 half 消息;

  5. 如果 Broker 收到的是 commit 请求,则把 half 消息投递到真实的队列等待库存服务来拉取,然后删除保存的 half 消息;

  6. 如果 Broker 没有收到请求,则会发送请求到 Producer 查询本地事务状态,然后根据 Producer 返回的本地状态做 commit/rollback 相关处理。

Seata 的改进

Seata 的改进主要在 prepare 阶段。Seata 提供了一个 SeataMQProducer 类,把 RocketMQ 中 TransactionListener 的方法加入到全局事务。见下面代码:

SeataMQProducer(final String namespace, final String producerGroup, RPCHook rpcHook) {super(namespace, producerGroup, rpcHook);this.transactionListener = new TransactionListener() {@Overridepublic LocalTransactionState executeLocalTransaction(Message msg, Object arg) {return LocalTransactionState.UNKNOW;}@Overridepublic LocalTransactionState checkLocalTransaction(MessageExt msg) {String xid = msg.getProperty(PROPERTY_SEATA_XID);if (StringUtils.isBlank(xid)) {LOGGER.error("msg has no xid, msgTransactionId: {}, msg will be rollback", msg.getTransactionId());return LocalTransactionState.ROLLBACK_MESSAGE;}GlobalStatus globalStatus = DefaultResourceManager.get().getGlobalStatus(SeataMQProducerFactory.ROCKET_BRANCH_TYPE, xid);if (COMMIT_STATUSES.contains(globalStatus)) {return LocalTransactionState.COMMIT_MESSAGE;} else if (ROLLBACK_STATUSES.contains(globalStatus) || GlobalStatus.isOnePhaseTimeout(globalStatus)) {return LocalTransactionState.ROLLBACK_MESSAGE;} else if (GlobalStatus.Finished.equals(globalStatus)) {LOGGER.error("global transaction finished, msg will be rollback, xid: {}", xid);return LocalTransactionState.ROLLBACK_MESSAGE;}return LocalTransactionState.UNKNOW;}};
}

在 prepare 阶段,SeataMQProducer 向 RocketMQ Broker 发送 half 消息,执行本地事务,如果执行成功,则强行把 LocalTransactionState 改回 UNKNOW,等待 TC 发送指令,决定是 commit 或 rollback。如果执行失败,返回 ROLLBACK_MESSAGE,TC 下发指令,回滚全局事务。

需要注意的是,Broker 收到 half 消息后,如果没有收到 commit/rollback 消息,则会回查 Producer 本地事务状态,也就是上面代码中的 checkLocalTransaction。这里不是检查分支事务状态,而是检查全局事务状态,使用 XID 去查询。

集成 RocketMQ 之后,Seata 的分布式事务调用流程如下图,这里以 订单服务、库存服务两个服务为例:

总结

Apache Seata 引入 RocketMQ 后,支持的分布式事务场景更加丰富,MQ 的异步特性也让事务模型整体性能提升。希望本文对你理解 Seata 中 RocketMQ 的使用有所帮助。

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

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

相关文章

Vue Router实现路由懒加载

为了提高页面的加载速度,我们可以使用Vue Router的路由懒加载功能。路由懒加载是什么呢,路由懒加载就是只有当访问某个路由的时候再加载其相应的页面。 官方文档地址https://router.vuejs.org/guide/advanced/lazy-loading.html 以前我写路由懒加载的时候…

详细教程:使用Grafana监控Mysql

什么是Grafana Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展 示,并及时通知。 下载Grafana 下载地址: https://grafana.com/grafana/download [rootgrafana ~]# wget https://dl.grafana.com/oss/relea…

qt QPushButton详解

QPushButton是Qt Widgets模块中的一个基本控件,用于提供可点击的按钮。它是用户界面中最为常见和常用的控件之一,通过点击按钮,用户可以触发特定的应用程序操作。 重要方法 QPushButton(const QIcon &icon, const QString &text, QWi…

【OpenAI】第五节(图像生成)利用 OpenAI 的 DALL·E 实现自动化图像生成:从文本到图像的完整教程

引言 OpenAI 推出的 DALLE 工具因其能够生成令人惊叹的艺术作品而备受瞩目。DALLE 不仅能够生成静态图像,还能根据用户的需求进行风格化处理,创造出独特的艺术作品。通过 OpenAI 的 API,你可以轻松将 DALLE 的强大功能集成到你的 Python 程序…

《分布式机器学习模式》:解锁分布式ML的实战宝典

在大数据和人工智能时代,机器学习已经成为推动技术进步的重要引擎。然而,随着数据量的爆炸性增长和模型复杂度的提升,单机环境下的机器学习已经难以满足实际需求。因此,将机器学习应用迁移到分布式系统上,成为了一个不…

Xcode16 编译运行YYCache iOS18 sqlite3_finalize 闪退问题解决方案

问题原因 升级Xcode 16 之后,真机运行APP,发现会有Crash,崩溃堆栈线上Crash 在 YYCache 之中。如下图所示 崩溃堆栈如下: * thread #1, queue com.apple.main-thread, stop reason signal SIGABRTframe #0: 0x00000001d9391…

免费开源Odoo软件如何实现电商仓库高效发货

世界排名第一的免费开源ERP软件Odoo,拥有非常强大的仓库管理WMS功能。本文以电商仓库发货管理为例,介绍电商订单的仓库发货作业的各种方法。电商订单仓库发货流程,通常分为三个步骤,即拣货、打包、发货。根据仓库日处理订单数量的…

九、pico+Unity交互开发——触碰抓取

一、VR交互的类型 Hover(悬停) 定义:发起交互的对象停留在可交互对象的交互区域。例如,当手触摸到物品表面(可交互区域)时,视为触发了Hover。 Grab(抓取) 概念&#xff…

京东笔试题

和谐敏感词 🔗 题目地址 🎉 模拟 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();String s scanner.next();String[] words new String[…

【毕业设计】基于SpringBoot的网上商城系统

前言 🔥本系统可以选作为毕业设计,运用了现在主流的SSM框架,采用Maven来帮助我们管理依赖,所选结构非常合适大学生所学的技术,非常合适作为大学的毕业设计,难以适中。 🔥采用技术:Sp…

C++:模板(2)

目录 非类型模板参数 模板的特化 概念 函数模板特化 类模板特化 全特化 偏特化 模板的分离编译 分离编译的概念 模板的分离编译 ​编辑 模板总结 非类型模板参数 模板参数分为类型形参与非类型形参。 类型形参:在模板参数列表中,跟在class…

HttpURLConnection构造请求体传文件

HttpURLConnection构造请求体传文件 在Java中,使用HttpURLConnection构造请求体传输文件,你需要做以下几步: 1、创建URL对象指向你想要请求的资源。 2、通过URL打开连接,转换为HttpURLConnection实例。 3、设置请求方法为POST。 …

GB/T28181-2022规范解读、应用场景和技术实现探究

GB/T28181-2022和GB/T28181-2016区别 GB/T28181-2022《公共安全视频监控联网系统信息传输、交换、控制技术要求》与 GB/T28181-2016 相比,主要有以下区别: 术语和定义方面: 术语删减:GB/T28181-2022 删除了 “联网系统信息”“数…

Win安装Redis

目录 1、下载 2、解压文件并修改名称 3、前台简单启动 4、将redis设置成服务后台启动 5、命令启停redis 6、配置文件设置 1、下载 【下载地址】 2、解压文件并修改名称 3、前台简单启动 redis-server.exe redis.windows.conf 4、将redis设置成服务后台启动 redis-server -…

pikachu靶场CSRF-post测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、抓包使用burp生成csrf脚本 四、源代码分析 五、结论 一、测试环境 1、系统环境 渗透机:本机(127.0.0.1) 靶 机:本机(127.0.0.1) 2、使用工具/软件 Burp sui…

老机MicroServer Gen8再玩 OCP万兆光口+IT直通

手上有一台放了很久的GEN8微型服务器,放了很多年,具体什么时候买的我居然已经记不清了 只记得开始装修的时候搬家出去就没用了,结果搬出去有了第1个孩子,孩子小的时候也没时间折腾,等孩子大一点的时候,又有…

【去哪儿-注册安全分析报告-缺少轨迹的滑动条】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

RabbitMQ service is already present - only updating service parameters

Windows下卸载RabbitMQ之后,然后重新注册RabbitMQ服务的时候,报错以下信息: D:\software\rabbitmq-server-4.0.2\rabbitmq_server-4.0.2\sbin>D:\software\rabbitmq-server-4.0.2\rabbitmq_server-4.0.2\sbin\rabbitmq-service.bat install RabbitMQ service is already …

kafka自定义配置信息踩坑

org.apache.kafka.common.config.ConfigException: Invalid value 0 for configuration acks: Expected value to be a string, but it was a java.lang.Integer 场景描述: 单个kafka使用springboot框架自带的 yml 配置完全OK(因为底层会帮我们处理好类…

调查显示软件供应链攻击增加

OpenText 发布了《2024 年全球勒索软件调查》,强调了网络攻击的重要趋势,特别是在软件供应链中,以及生成式人工智能在网络钓鱼诈骗中的使用日益增多。 尽管各国政府努力加强网络安全措施,但调查显示,仍有相当一部分企…