从基础到进阶,一文详解RocketMQ事务消息,看完不会跪键盘

RocketMQ系列6——事务消息 RocketMQ在4.3.0版中支持分布式事务消息,这里RocketMQ的事务消息是采用2PC(两段式协议) +补偿机制(消息回查)的分布式事务功能。提供消息发送与业务落库的一致性。 阅读详情

本文转载自:从基础到进阶,一文详解RocketMQ事务消息,看完不会跪键盘


事务消息是RocketMQ提供的非常重要的一个特性,在4.x版本之后开源,可以利用事务消息轻松地实现分布式事务。本文对RocketMQ的事务消息进行详细介绍,并给出了代码示例。

一. 相关概念

RocketMQ在其消息定义的基础上,对事务消息扩展了两个相关的概念:

  • Half(Prepare) Message——半消息(预处理消息):半消息是一种特殊的消息类型,该状态的消息暂时不能被Consumer消费。当一条事务消息被成功投递到Broker上,但是Broker并没有接收到Producer发出的二次确认时,该事务消息就处于"暂时不可被消费"状态,该状态的事务消息被称为半消息。

  • Message Status Check——消息状态回查:由于网络抖动、Producer重启等原因,可能导致Producer向Broker发送的二次确认消息没有成功送达。如果Broker检测到某条事务消息长时间处于半消息状态,则会主动向Producer端发起回查操作,查询该事务消息在Producer端的事务状态(Commit 或 Rollback)。可以看出,Message Status Check主要用来解决分布式事务中的超时问题。

二. 执行流程

上面是官网提供的事务消息执行流程图,下面对具体流程进行分析:

  • Step1:Producer向Broker端发送Half Message;
  • Step2:Broker ACK,Half Message发送成功;
  • Step3:Producer执行本地事务;
  • Step4:本地事务完毕,根据事务的状态,Producer向Broker发送二次确认消息,确认该Half Message的Commit或者Rollback状态。Broker收到二次确认消息后,对于Commit状态,则直接发送到Consumer端执行消费逻辑,而对于Rollback则直接标记为失败,一段时间后清除,并不会发给Consumer。正常情况下,到此分布式事务已经完成,剩下要处理的就是超时问题,即一段时间后Broker仍没有收到Producer的二次确认消息;
  • Step5:针对超时状态,Broker主动向Producer发起消息回查;
  • Step6:Producer处理回查消息,返回对应的本地事务的执行结果;
  • Step7:Broker针对回查消息的结果,执行Commit或Rollback操作,同Step4。

三. 代码实例

本节通过一个简单的场景模拟RocketMQ的事务消息:存在2个微服务,分别是订单服务和商品服务。订单服务进行下单处理,并发送消息给商品服务,对于下单成功的商品进行减库存。

首先是订单服务:

/**
 * @Auther: ZhangShenao
 * @Date: 2019/3/27 16:44
 * @Description:使用RocketMQ事务消息——订单服务发送事务消息,然后进行本地下单,并通知商品服务减库存
 */
public class OrderService {
  public static void main(String[] args) throws Exception {
    TransactionMQProducer producer = new TransactionMQProducer();
    producer.setNamesrvAddr(RocketMQConstants.NAMESRV_ADDR);
    producer.setProducerGroup(RocketMQConstants.TRANSACTION_PRODUCER_GROUP);

    //自定义线程池,执行事务操作
    ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 50, 10L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(20), (Runnable r) -> new Thread("Order Transaction Massage Thread"));
    producer.setExecutorService(executor);

    //设置事务消息监听器
    producer.setTransactionListener(new OrderTransactionListener());

    producer.start();

    System.err.println("OrderService Start");

    for (int i = 0;i < 10;i++){
      String orderId = UUID.randomUUID().toString();
      String payload = "下单,orderId: " + orderId;
      String tags = "Tag";
      Message message = new Message(RocketMQConstants.TRANSACTION_TOPIC_NAME, tags, orderId, payload.getBytes(RemotingHelper.DEFAULT_CHARSET));

      //发送事务消息
      TransactionSendResult result = producer.sendMessageInTransaction(message, orderId);
      System.err.println("发送事务消息,发送结果: " + result);
    }
  }
}

事务消息需要一个TransactionListener,主要进行本地事务的执行和事务回查,代码如下:

/**
 * @Auther: ZhangShenao
 * @Date: 2019/3/27 16:50
 * @Description:订单事务消息监听器
 */
public class OrderTransactionListener implements TransactionListener {
  private static final Map<String, Boolean> results = new ConcurrentHashMap<>();

  @Override
  public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
    String orderId = (String) arg;

    //记录本地事务执行结果
    boolean success = persistTransactionResult(orderId);
    System.err.println("订单服务执行本地事务下单,orderId: " + orderId + ", result: " + success);
    return success ? LocalTransactionState.COMMIT_MESSAGE : LocalTransactionState.ROLLBACK_MESSAGE;
  }

  @Override
  public LocalTransactionState checkLocalTransaction(MessageExt msg) {
    String orderId = msg.getKeys();
    System.err.println("执行事务消息回查,orderId: " + orderId);
    return Boolean.TRUE.equals(results.get(orderId)) ? LocalTransactionState.COMMIT_MESSAGE : LocalTransactionState.ROLLBACK_MESSAGE;
  }

  private boolean persistTransactionResult(String orderId) {
    boolean success = Math.abs(Objects.hash(orderId)) % 2 == 0;
    results.put(orderId, success);
    return success;
  }
}

下面是商品服务及监听器:

/**
 * @Auther: ZhangShenao
 * @Date: 2019/3/27 17:09
 * @Description:使用RocketMQ事务消息——商品服务接收下单的事务消息,如果消息成功commit则本地减库存
 */
public class ProductService {
  public static void main(String[] args) throws Exception {
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer();
    consumer.setNamesrvAddr(RocketMQConstants.NAMESRV_ADDR);
    consumer.setConsumerGroup(RocketMQConstants.TRANSACTION_CONSUMER_GROUP);
    consumer.subscribe(RocketMQConstants.TRANSACTION_TOPIC_NAME, "*");
    consumer.registerMessageListener(new ProductListener());
    consumer.start();
    System.err.println("ProductService Start");
  }
}
/**
 * @Auther: ZhangShenao
 * @Date: 2019/3/27 17:14
 * @Description:
 */
public class ProductListener implements MessageListenerConcurrently {
  @Override
  public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
    Optional.ofNullable(msgs).orElse(Collections.emptyList()).forEach(m -> {
      String orderId = m.getKeys();
      System.err.println("监听到下单消息,orderId: " + orderId + ", 商品服务减库存");
    });
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
  }
}

分别运行OrderService和ProductService,可以看出只有事务执行成功的订单才会通知商品服务进行减库存。

监听到下单消息,orderId: f25a7127-307e-45ce-8f83-6e0a922ebb94, 商品服务减库存
监听到下单消息,orderId: d960171d-97c0-4e13-aa4a-c2b96102de4b, 商品服务减库存
监听到下单消息,orderId: 63aedaa2-ce74-4cb7-bf58-fb6a73082a73, 商品服务减库存
监听到下单消息,orderId: 25764461-70b2-44db-8296-960211179e6e, 商品服务减库存
监听到下单消息,orderId: fb319fe7-c8be-4edf-ae4e-6108898068ca, 商品服务减库存
监听到下单消息,orderId: 4f61a61a-7254-458a-bc10-9d4006a9f581, 商品服务减库存

本文转载自:从基础到进阶,一文详解RocketMQ事务消息,看完不会跪键盘

“华为杯”研究生数学建模竞赛2019年-【华为杯】D题:汽车行驶工况构建(附获奖论文和MATLAB代码实现) 映了汽车道路行驶的运动学特征。准差、加速度标准差这九个特征参数用于后续的数据分析,建立了合理的汽车运动特征评。特征参数与所属类特征参数的特征值的相关性大小替代误差进行排序的,计算得到汽车行。对于问题一,我们首先对原始数据进行了时间变量转换,将原本的年月日时分秒的计。紧接着进行了运动学片段的划分,引入九个特征参数,通过主成分分析、本文研究的是汽车行驶工况构建,汽车行驶工况是描述汽车行驶的速度。的合理性评价标准,对两种方法都进行了合理性评价,得到的。进行了合理性评价,得到了最优的汽车行驶工况曲线。 阅读详情

相关推荐

Ansys Lumerical + HFSS + optiSLang 三剑客:手把手教你优化行波MZM调制器(附完整参数配置)

本文详细介绍了如何利用Ansys Lumerical、HFSS和optiSLang三款工具构建自动化协同设计流程,以优化行波马赫曾德尔调制器(TW-MZM)的性能。通过参数化仿真、流程集成与元模型技术,该方案能高效解决多物理场耦合挑战,实现调制带宽、驱动电压等多目标的全局优化,显著提升光子集成芯片的设计效率与性能潜力。

weixin_29251131的博客 585

RocketMQ事务消息

RocketMQ 事务消息

qq_42877546的博客 1万+

Android车载桌面开发实战:从CarLauncher源码解析到自定义Launcher开发(Android 11)

本文深入解析了Android 11中CarLauncher的源码架构与核心模块,并提供了从零开始定制开发车载Launcher的完整实战指南。内容涵盖车载桌面的独特定位、驾驶场景优化、多屏协同、动态内容嵌入等核心挑战,以及如何构建符合安全规范、体验流畅的自定义车载桌面应用,是车载应用开发者提升系统级定制能力的实用参考。

weixin_29266647的博客 515

RocketMQ事务消息详解

Apache RocketMQ在4.3.0版中已经支持分布式事务消息,采用了2PC(两阶段提交)+ 补偿机制(事务状态回查)的思想来实现了提交事务消息,同时增加一个补偿逻辑来处理二阶段超时或者失败的消息,如下图所示。总的来说,RocketMQ 事务消息在确保消息可靠传递的同时,也需要开发者按照一定的规范来设计和实现本地事务执行器,以及处理可能的回查请求,这些都是在使用 RocketMQ 事务消息时需要考虑和遵循的限制。事务消息的生产者 ID 不能与其他类型消息的生产者 ID 共享。

刘皇叔说Java的博客 4139

Codesys电子凸轮从入门到应用:手把手教你用MC_CamIn/MC_CamOut实现主从轴同步

本文详细介绍了如何在Codesys平台上使用MC_CamIn和MC_CamOut功能块实现电子凸轮的主从轴同步控制。从环境配置、轴使能到凸轮表创建与动态切换,提供了完整的程序编写指南和调试技巧,帮助工程师快速掌握工业自动化中的高精度运动控制技术。

weixin_26878995的博客 277

激光SLAM总结——Fast LIO / Fast LIO2 / Faster LIO

激光SLAM总结——Fast LIO / Fast LIO2 / Faster LIO 在之前的工作中有接触过LOAM,最近在工作中又接触到Faster LIO相关的工作,于是想着对Fast LIO / Fast LIO2 / Faster LIO这一系列工作进行一个简单的总结,以加深自己对激光SLAM算法的理解,之前总结过的一些和激光SLAM算法相关的博客还有,感兴趣的同学可以一起学习讨论: 激光SLAM总结——VLOAM / LIMO算法解析 激光SLAM总结——LIO-Mapping / LIOM /

weixin_44580210的博客 1万+

RocketMQ之三----事务消息

根据半事务消息Topic RMQ_SYS_TRANS_HALF_TOPIC 和处理半事务消息Topic RMQ_SYS_TRANS_OP_HALF_TOPIC 差值判断需要回查的半事务消息,发CHECK_TRANSACTION_STATE回查指令到业务方查询本地事务执行结果。RMQ_SYS_TRANS_OP_HALF_TOPIC 已处理的半事务消息topic,body存的是半事务消息Topic 的消息位移,同一个queue下,用逗号分隔(另有线程处理)然后保存并返回结果(到此完成发送半事务消息)。

枫火的博客 2970

【GlobalMapper精品教程】006:Excel表格(.xls)或文本(.txt .csv)坐标文件生成矢量点

原始的坐标数据如下图所示,其中坐标为Lat经度,LNG纬度,均为十进制度的形式,一般软件都支持十进制度的格式,如果不支持,你可以尝试使用度分秒的形式,图中的DDMMSS-LAT为纬度,DDMMSS-LNG为经度。打开globalmapper软件,点击【打开数据文件】,选择坐标数据文件(案例中的数据位配套实验数据包中的data006.rar)气象台站分布点坐标.xls。选择坐标系:本案例数据采用的是经纬度,因此选择Geographic(Latitude/Longitude),基准选择WGS84,点击确定。

智慧空间实验室 2569

科普文:微服务之Spring Cloud Alibaba消息队列组件RocketMQ工作原理

事务消息是为了保证分布式系统中消息的一致性而引入的一种消息类型。事务消息允许消息发送方在发送消息后,进行本地事务操作,并根据本地事务的执行结果来决定消息的最终状态(提交或回滚)。

为无为,事无事,味无味。 1299

[RK3568 Android11] 开发之调试RK809 codec音频-SPK喇叭

目录 前言 一、注册声卡顺序 二、SPK喇叭路由配置 三、tinyalsa调试工具 前言 瑞芯微RK809是一种复杂的功率管理集成电路(PMIC)集成编解码器,适用于由外部电源供电的多核系统应用;同时它也集成了音频编解码器,这样在硬件设计上可以直接使用RK809 codec功能,不必再外挂个其他codec芯片;RK809 codec不仅支持SPK,还支持耳机,MIC功能; 一、注册声卡顺序 设备树dts里面原厂帮我们配置好了rk809_sound,我们直接...

~未来可期~ 7412

7.19华为OD机试真题 新系统 - 物流仓储多维度成本利润综合查询系统 (Java/Py/C/C++/Js/Go)

7.19华为OD机试真题 新系统 - 物流仓储多维度成本利润综合查询系统 (Java/Py/C/C++/Js/Go)

算法大师! 616

【Java进阶营】从基础到进阶,一文详解RocketMQ事务消息,看完不会跪键盘

事务消息是RocketMQ提供的非常重要的一个特性,在4.x版本之后开源,可以利用事务消息轻松地实现分布式事务。本文对RocketMQ的事务消息进行详细介绍,并给出了代码示例。 一. 相关概念 RocketMQ在其消息定义的基础上,对事务消息扩展了两个相关的概念: Half(Prepare) Message——半消息(预处理消息):半消息是一种特殊的消息类型,该状态的消息暂时不能被Consumer消费。当一条事务消息被成功投递到Broker上,但是Broker并没有接收到Producer发出的二次确认.

864

【ARM Coresight | AMBA BUS | Cache 与 MMU/MPU | CoreLink | GCC | CSH 专栏导读】

1. ARM Coresight(SoC-400/SoC-600) 专栏 2. ARMv8/v9 CPU/Cache 专栏 3. Linux ARM AMBA 总线 专栏 4. Trace32/DS-5 专栏。。。

CodingCos的博客 8241

面试官:RocketMQ是什么,它有什么特性与使用场景?

面试官:RocketMQ你很精通吗?

真正的大师永远怀着一颗学徒的心 7260

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

RocketMQ的运行架构&理解RocketMQ的消息模型

通过之前的一系列实验,相信你对RocketMQ的运行机制有了一个大概的了解。接下来我们结合一下之前实验的过程,来理解一下RocketMQ的运行架构。下图是RocketMQ运行时的整体架构:

· 813

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

最详细的docker安装rocketMQ教程来了

RocketMQ是一款分布式、队列模型的消息中间件,是由阿里巴巴设计的,具有以下特点: 支持严格的消息顺序 支持Topic与Queue两种模式 亿级消息堆积能力 比较友好的分布式特性 同时支持Push与Pull方式消费消息 历经多次天猫双十一海量消息考验 RocketMQ是纯java编写,基于通信框架Netty。 ...

小泽 6210

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Docker以挂载方式安装RocketMQ

在 Docker 中安装和使用 RocketMQ 有多种方式,其中一种方式就是通过挂载本地文件的方式安装 RocketMQ。挂载的方式可以避免重启Docker镜像后,原配置丢失的问题。现在,可以使用浏览器访问 http://[your_server_ip]:9999/来访问控制台。第一次安装RocketMQ时难免踩坑,但是请保持平和心态对待,不要担心,自己遇到的问题,别人一定遇到过,肯定有解决方案。如果你还没有安装 Docker,请先安装。创建一个新的容器并指定 RocketMQ 的镜像。

weixin_43811057的博客 1362

【Spring Cloud Alibaba】RocketMQ(一)

MQ:MessageQueue,消息队列。是在互联⽹中使⽤⾮常⼴泛的⼀系列服务中间件。这个词可以分两个部分来看,⼀是Message:消息。消息是在不同进程之间传递的数据。这些进程可以部署在同⼀台机器上,也可以分布在不同机器上。⼆是Queue:队列。队列原意是指⼀种具有FIFO(先进先出)特性的数据结构,是⽤来缓存数据的。对于消息中间件产品来说,能不能保证FIFO特性,尚值得考量。但是,所有消息队列都是需要具备存储消息,让消息排队的能⼒。

Blue_Pepsi_Cola的博客 231

RabbitMQ、RocketMQ、Kafka、ActiveMQ

RabbitMQ、RocketMQ、Kafka、ActiveMQ 注: 由于本猿键盘Q键坏了,时好时坏,所以下文中的 rabbitmq == rabbitm 消息中间件: 消息中间件指的是利用高效可靠的消息传递机制进行跨进程、与平台无关的数据交流,可以在分布式环境下扩展进程的通信 目前主流的消息中间件有 ActiveMQ、Kafka、RabbitMQ、RocketMQ等 MQ使用场景: mq使用场景很多,主要有三个: 解耦、异步、削峰 解耦: 解耦主要指的是 A 系统需要与 B C D 系统实现数据交互(

后端为主,前端为辅。 489

RocketMQ源码详解系列1 《源码调试环境搭建》

1.今天我们来搭建下rocket源码调试环境。 windows eclipse + jdk8 + maven 2.下载源码 https://github.com/apache/rocketmq 3.在eclispe中导入maven项目 rocketmq-master 4.新增conf目录 (D:\dev\java_workspace\rocketmq\conf) 把如下4个配置文件放入到D:\d...

吉他程序员的博客 451

docker选择安装位置_docker安装rocketMQ教程(最详细)

RocketMQ是一款分布式、队列模型的消息中间件,是由阿里巴巴设计的,具有以下特点:支持严格的消息顺序支持Topic与Queue两种模式亿级消息堆积能力比较友好的分布式特性同时支持Push与Pull方式消费消息历经多次天猫双十一海量消息考验RocketMQ是纯java编写,基于通信框架Netty。其实小编就冲着RocketMQ历经多次天猫双十一海量消息考验,就感觉应该选择他了,再加上有亿级消息堆...

weixin_35728089的博客 1159

前后端都用的编程模型--消息队列

我们现在能收发微信、浏览网页,习以为常的活动的背后,都有一个共同的编程模型起作用。今天来解开这模型的面纱。。。

qq_24641555的专栏 425

RocketMQ Summit 2022 案例征集中

日前,优秀案例征集通道已开放!定制礼品、Cherry 键盘等丰厚礼品等您来拿!更有现场授奖,荣誉与奖牌向您一齐奔赴而来!

阿里巴巴云原生的博客 238

Rocketmq 双Master环境搭建

服务器及环境 IP 别名 模式 192.168.11.12 rocketmq-nameserver1、rocketmq-master1 Master 192.168.11.13 rocketmq-nameserver2、rocketmq-master2 Master 修改/etc/hosts vi /etc/hosts 添加如下内容 192.168.11.12 rock...

weixin_43865893的博客 207

RocketMQ(三)——HelloWorld

讲个9·3阅兵时程序员间流传的笑话: 同学们,现在向我们走来的是程序员方阵!他们穿着拖鞋,披着毛巾,左手拿着键盘,右手举着鼠标,腋下夹着USB转换器。他们因睡眠不足而显得精神不振,喊着微弱的口号走过主席台,主席问候:程序员们辛苦了!程序员方队异口同声地答道:Hello World! ——研究一项技术,如果不提及“Hello World”,那指定是外行。

张连海 1万+
上一篇: 2020金三银四,这是我的Java线程池学习总结,请笑纳!
下一篇: Java程序员2020刚开始找工作就碰壁?建议看完这份春招面试大纲
Java_supermanNO1
博客等级 码龄7年 1170粉丝 329原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值