RocketMQ中事务消息的实现机制

RocketMQ的事务消息实现原理与Kafka的事务机制差异 RocketMQ和Kafka事务机制对比分析:RocketMQ采用两阶段提交(2PC)实现事务消息,通过半消息和自动回查机制保障原子性,开发简单且隔离性强,适合金融支付等强一致性场景(吞吐10-50万/秒,延迟20-100ms)。Kafka依赖事务协调器和幂等生产者,吞吐更高(100-200万/秒)但需复杂配置,适合流处理等最终一致性场景。RocketMQ优势在于低业务侵入性、灵活的顺序控制和主动回查机制,而Kafka在纯吞吐性能上更优。选型需根据业务场景的可靠性要求与性能需求权衡。 阅读详情

        在分布式系统中,确保消息与本地事务的一致性是一个关键问题。RocketMQ通过事务消息提供了对这种需求的支持,其核心思想是通过两阶段提交来确保消息和本地事务的原子性。本文将深入探讨RocketMQ事务消息的实现机制,包括基本流程、事务回查机制以及消息状态的处理。

 一、事务消息的基本流程

 (一)第一阶段:半消息的发送

        当生产者发送事务消息时,RocketMQ会将消息存储在一个特殊的队列RMQ_SYS_TRANS_HALF_TOPIC中,并将其标记为“半消息”,此时消费者无法看到该消息。随后,生产者会执行本地事务,并根据事务的结果决定提交或回滚。

- 事务成功:生产者提交事务,通知RocketMQ将半消息转为正式消息。

- 事务失败:生产者回滚事务,RocketMQ会删除该半消息。

 (二)第二阶段:事务提交与回滚

- 提交操作:生产者确认事务成功时,发送COMMIT_MESSAGE操作,RocketMQ将半消息转为正式消息,消费者可以消费该消息。

- 回滚操作:如果事务失败,生产者发送ROLLBACK_MESSAGE操作,RocketMQ会丢弃该半消息,消费者无法消费。

 二、事务回查机制

        在实际场景中,生产者可能因为网络问题、程序崩溃等原因无法及时提交或回滚事务。为了确保消息与本地事务的一致性,RocketMQ引入了事务回查机制。

        当RocketMQ检测到某条半消息长时间未提交或回滚时,会主动发起回查请求。生产者需要实现checkLocalTransaction方法,以返回事务的执行状态:

- 事务成功:返回COMMIT_MESSAGE,RocketMQ将半消息提交。

- 事务失败:返回ROLLBACK_MESSAGE,RocketMQ会丢弃消息。

- 状态未知:返回UNKNOWN,RocketMQ会再次回查。

 三、消息的三种状态

RocketMQ事务消息有三种状态:

1. COMMIT_MESSAGE:本地事务成功,消息可以投递给消费者。

2. ROLLBACK_MESSAGE:本地事务失败,消息被丢弃。

3. UNKNOWN:事务状态无法确定,RocketMQ会继续回查。

 四、源码解析

 (一)sendMessageInTransaction方法解析

        生产者通过sendMessageInTransaction方法发送事务消息。该方法首先将消息标记为事务消息,并发送到RocketMQ。消息被存储在RMQ_SYS_TRANS_HALF_TOPIC队列中,直到本地事务完成。

public SendResult sendMessageInTransaction(Message msg, LocalTransactionExecuter transactionExecuter, Object arg) throws MQClientException {
    // 设置事务标志
    msg.putUserProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED, "true");
    
    // 发送消息至 Broker
    SendResult sendResult = producer.send(msg);
    
    // 执行本地事务
    transactionExecuter.executeTransaction(msg, arg);
    
    return sendResult;
}

 (二)Broker处理事务消息

        RocketMQ的Broker会接收到事务消息,并将其存储在特殊队列RMQ_SYS_TRANS_HALF_TOPIC中。此时,消费者无法看到这些消息。Broker会检查消息是否为事务消息,如果是事务消息,则会将其状态设置为“半消息”,并等待生产者提交或回滚事务。

public void sendMessage(SendMessageRequestHeader requestHeader, Message msg) {
    // 检查消息是否为事务消息
    if (msg.getProperties().containsKey(MessageConst.PROPERTY_TRANSACTION_PREPARED)) {
        // 事务消息处理
        messageQueue = new MessageQueue(RMQ_SYS_TRANS_HALF_TOPIC, "0");
        msg.setTopic(RMQ_SYS_TRANS_HALF_TOPIC);
    }
    // 存储消息
    brokerController.getMessageStore().putMessage(msg);
}

 (三)事务提交与回滚

        当生产者决定提交或回滚事务时,RocketMQ的Broker会通过EndTransactionProcessor处理请求,根据事务状态将消息移出半消息队列,放入正式队列或丢弃。

public void processRequest(ChannelHandlerContext ctx, EndTransactionRequestHeader requestHeader) {
    if (requestHeader.getTransactionStatus() == TransactionStatus.CommitMessage) {
        // 提交事务,移动消息至正式队列
        brokerController.getMessageStore().putMessage(requestHeader.getMessage());
    } else if (requestHeader.getTransactionStatus() == TransactionStatus.RollbackMessage) {
        // 回滚事务,删除半消息
        brokerController.getMessageStore().deleteMessage(requestHeader.getMessage());
    }
}

 (四)事务回查

                如果半消息未被确认,RocketMQ会定期扫描RMQ_SYS_TRANS_HALF_TOPIC队列,并发起回查请求。生产者通过checkLocalTransaction方法返回事务状态。

public TransactionStatus checkLocalTransactionState(Message msg) {
    // 检查本地事务状态
    boolean success = localTransactionService.checkTransactionStatus(msg);
    if (success) {
        return TransactionStatus.CommitMessage;
    } else {
        return TransactionStatus.RollbackMessage;
    }
}

 五、总结

RocketMQ通过两阶段提交机制实现了事务消息,确保了消息与本地事务的一致性。事务消息的实现包括以下关键步骤:

1. 生产者发送半消息至RocketMQ。

2. 生产者执行本地事务,并根据结果提交或回滚事务。

3. 如果生产者未能及时确认,RocketMQ会通过事务回查机制确保消息状态的一致性。

事务消息的三种状态(COMMIT_MESSAGE、ROLLBACK_MESSAGE、UNKNOWN)以及事务回查机制,使得RocketMQ能够在分布式环境中可靠地处理事务消息。

RocketMQ的事务消息是如何实现的? 那如果用事务消息,先提交一个半消息,然后执行本地事务,在发送一个commit的半消息。4.回滚事务消息:如果本地事务执行失败,应用程序通知RocketMQ Broker 回滚该事务,RocketMQ将该消息的状态从‘prepared’改为‘rollback’,并将该消息从事务消息日志中删除,从而保证该消息不会被消费者消费。在发送事务消息时,首先向RocketMQ Broker 发送一条‘half消息’(半消息),半消息将被存储在broker端的事务消息日志中,但是这个消息还不能被消费者消费。 阅读详情

相关推荐

RocketMQ系列6——事务消息

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

xiaodigua1024的博客 2804

RocketMQ进阶-事务消息

这个月马上就又要过去了,还在找工作的小伙伴要做好准备了,小编整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家;这一块的代码逻辑都是在生产端,即Order-Server,大家不要搞错了这个月马上就又要过去了,还在找工作的小伙伴要做好准备了,小编整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家[外链图片转存中…(img-M5SsUCsG-1714443570462)][外链图片转存中…(img-qzj9SZPw-1714443570462)]本文已被。

2301_79987255的博客 941

RocketMq事务消息(分布式事务解决方案)

从问题出发 阅读本文后,我们将了解以上两个问题的答案。 1、RocketMq生产者组(producer group)的设定有什么用? 2、一个订单处理的场景,消费者订阅了订单topic,但总担心丢消息。于是为了防止丢消息,每天都会通过定时任务做一致性校验,这是最佳方案吗? 这还得从基于消息队列实现实现分布式事务的解决方案说起。 常见的分布式事务包括 2PC、3PC、TCC、本地消息表、消息事务、最大努力通知。 今天我们主要讲讲本地消息表、消息事务两种方案。 本地消息表 本地消息表的大致流程是这样的。 pub

疯狂的蜗牛 9425

RocketMQ事务实例

生成者:发送半消息 使用很简单,但是参数还是说明一下吧: //可以自定义些MQ配置参数,我们这里不需要所以一切默认 @Autowired private RocketMQTemplate rocketMQTemplate; public TransactionSendResult sendMessageInTransaction(String txProducerGroup, String destination, Message<?> messa.

天生我材必有用,千金散尽还复来。 1341

RocketMQ 和 Kafka 的事务消息实现原理和机制

RocketMQ 和 Kafka 都提供了事务消息的功能,通过不同的机制实现了事务消息的可靠性和一致性。RocketMQ 使用事务 ID 和消息状态来管理事务消息,并通过消息回查机制来保证事务的最终一致性;而 Kafka 则使用事务日志和事务操作来管理事务消息,并通过提交或中止事务来确保消息的一致性。需要注意的是,以上是对 RocketMQ 和 Kafka 事务消息实现的简要介绍,实际应用中可能还涉及到更复杂的配置和实现细节,开发人员在使用时需要仔细阅读官方文档并按照最佳实践进行配置和使用。

TechInk的博客 256

vcpkg管理OpenCASCADE的5个高效技巧:从多版本共存到离线部署

本文详细介绍了使用vcpkg高效管理OpenCASCADE的5个实用技巧,包括多版本共存、性能优化、团队共享、CI/CD集成和离线部署。通过自动配置和版本控制,vcpkg显著简化了OpenCASCADE的开发环境管理,特别适合工业级CAD开发场景。

rain6的博客 185

28 RocketMQ:事务消息机制的底层实现原理

1.half 消息在commit前对消费者不可见的原因 回顾:当订单系统去发送一个half消息给MQ的时候。对于这个half消息,红包系统在这时是看不到它的,也无法去消费这条消息并进行处理。 ConsumeQueue的可见原理 场景解析:当写入一条half消息到OrderPaySuccessTopic这个Topic里去,会定位到这个Topic的一个MessageQueue,然后定位到上图RocketMQ的一台机器上去,接着,消息就会写入到CommitLog中。 与此同时,消息的offset会写入Me

喜欢历史的码农 588

自抗扰控制ADRC原理解析及案例应用

ESO的设计通常基于系统动态方程的线性化或近似模型,其输出包括系统状态的估计值和总扰动的估计值。非线性状态误差反馈控制律(Nonlinear State Error Feedback,NLSEF)是ADRC的最后一个环节,负责根据ESO和TD提供的信息生成控制信号。ADRC的另一个重要发展方向是与其他控制策略的融合,如模糊控制、神经网络和自适应控制等,以进一步提高系统的鲁棒性和适应性。ADRC的参数主要包括扩张状态观测器(ESO)的参数和非线性状态误差反馈控制律(NLSEF)的参数。

LIUMAO99的博客 9257

RocketMQ半消息对消费者不可见是如何实现的?——事务消息机制揭秘

首发于工号【BiggerBoy】,——“半消息藏在这里,但为什么你偷看也没用?上篇中提到“TBW102是RocketMQ预留的事务消息Topic”,是什么意思?为什么消费者看不到半消息?是如何实现的?带着这些疑问,开启今天的探索之旅!这句话隐藏的意思就是:生产者发送事务消息时实际Broker会把半消息存储到TBW102这个Topic。当生产者通知Broker提交时,Broker会将消息发送到生产者指定的Topic,此时消费者才能消费该消息。

weixin_35713824的博客 99

电子设计实战:用MOS管手把手搭建D触发器电路(含时序分析避坑指南)

本文详细介绍了如何使用MOS管从零开始搭建D触发器电路,重点解析了建立时间和保持时间等关键时序参数对电路稳定性的影响。通过实测波形分析和避坑指南,帮助电子工程师掌握D触发器的实际搭建技巧与优化方法,提升数字电路设计的可靠性。

x1y2z的博客 1153

医疗领域BGE-M3模型微调全流程:从数据准备到效果评估

本文详细介绍了医疗领域BGE-M3模型的微调全流程,从数据准备到效果评估。通过医疗数据微调,BGE-M3模型在临床问答、病历检索等场景中表现显著提升,能够准确理解医学术语之间的细微差别。文章还提供了实战练习代码和效果评估指标,帮助开发者快速掌握医疗文本嵌入模型的应用技巧。

weixin_29098367的博客 278

深入探究 RocketMQ 事务机制的实现流程,为什么它能做到发送消息零丢失?

本文转载自公众号:石杉的架构笔记本文来自狸猫技术窝专栏《从零开始带你成为消息中间件实战高手》,是作者原子弹大侠开放的试读1、解决消息丢失的第一个问题:订单系统推送消息领丢失既然我们已经明...

架构师小秘圈 145

fastbin attack快速入门

0x01 fastbin简介 Fastbin包含0x20~0x80大小bin的数组指针,用于快速分配小堆块。fastbin按照单链表结构进行组织,相同大小的bin在同一个链表中,fd指向下一个bin,采用LIFO(Last In First Out)机制。在fastbin中,堆块的inuse标志都为1,处于占用状态,防止chunk释放时进行合并,加快小堆块的分配。 正常fastbin的使用 通过这个简单的案例来了解fastbin的单链表结构,malloc和free的过程。 #include<stdio

abelxu 1567

RocketMQ(九):rocketMQ设计的全链路消息零丢失方案?+rocketmq消息中间件事务消息机制的底层实现原理?+half是什么?+half消息是如何对消费者不可见的?

前言: 目前rocketmq更新已经更新了11篇博客了,预计接下来的2-3篇是暂时的更新进度了,准备更新一下springboot或者是jvm,mysql相关的专题出来,后续更新完事后,再分享一些实战性的案例出来,方便加深理解,也感谢一路看到这里的同仁; 1.屁话不多说,开局一张图(mq事务机制执行流程图) 2.分析从producer–>rocketmq–>consumer成功消费要打多少怪兽 1.订单系统推送消息到mq的过程是否会发生数据丢失? 当然可能会丢失:网络出现抖动,发送消息失败

weixin_46950473的博客 1828

一文吃透 SAP IDoc 状态码:从 TEDS1 到 WE02 排障,再到 ABAP 自动化监控

在 SAP 集成场景里,IDoc 往往是最常见、也最容易被低估的一条生命线:采购订单、发票、主数据、库存移动……只要系统之间要稳定地交换结构化业务数据,IDoc 就经常登场。真正让人头疼的,并不是 IDoc 本身,而是它在链路里到底走到了哪一步、卡在了哪里、该找谁背锅。这篇文章把常用的 IDoc 状态码按出站、入站拆开讲清楚,并且把每个状态对应的真实世界故障现象、排查入口、以及可以落地的 ABAP 监控代码串起来,让你看到状态码就能想到动作。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 397

把 LangGraph 当“工作流引擎”用:与传统 BPM 的差异与融合策略

首先,我们来回顾一下有限状态机(FSM)的基本定义——一个 FSM 可以用一个五元组MQΣδq0FMQΣδq0​FQQQ有限状态集合,包含 FSM 所有可能的状态;Σ\SigmaΣ有限输入字母表,包含 FSM 所有可能的输入;δ\deltaδ状态转移函数,定义了 FSM 从当前状态q∈Qq \in Qq∈Q接收输入σ∈Σσ∈Σ后,转移到的下一个状态q′∈Qq' \in Qq′∈Q,即δQ×Σ→QδQ×Σ→Q。

AI 原生应用开发的博客 223
上一篇: 字符流在处理不同编码文件时的工作原理
下一篇: 消息队列的特性与使用场景:Kafka、ActiveMQ、RabbitMQ与RocketMQ的深度剖析
啊sen丶
博客等级 码龄4年 226粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值