最后更新:2026-10-23 · 基于第 1 次作答
结论:回查是 Broker 对"半消息已落地但生产者没给结论"的兜底机制,让事务消息在生产者崩溃时仍能收敛。 关键词:半消息 · 回查 · 递增间隔 · 最大回查次数 边界:回查只判断本地事务状态,不能替代业务幂等与对账。
核心考点定位:能否说清回查的触发原因(生产者失联)、判定依据(本地事务状态)和收敛规则(超时后按失败处理)。
机制链(≥3 环):
证据锚点:
半消息(Half Message):已落库但对消费者不可见的消息状态。transactionCheckMax:最大回查次数,默认 15 次。transactionCheckInterval:回查间隔,默认 60 秒,且间隔递增。checkLocalTransaction:生产者实现的回查回调,返回 Commit / Rollback / Unknown。事务状态表:回查判定的依据,必须与本地事务同库同事务写入。死信队列:多次回查失败后的最终去向,需人工介入。对比与权衡:
| 方案 | 半消息机制 | 回查主体 | 收敛依据 | 适用边界 |
|---|---|---|---|---|
| RocketMQ 事务消息 | 内置 | Broker 主动回查 | 生产者状态回调 | 生产者与 Broker 同集群可达 |
| 本地消息表 | 无 | 业务方扫表 | 业务方状态表 | 业务方运维能力强 |
| TCC | 无 | TC 回查分支 | 分支事务状态 | 核心账务、需强控制 |
常见误区:
适用边界:回查解决的是"生产者失联",不解决"消费者处理失败";后者要靠消费端重试、幂等和死信队列。
【结论】 面试官您好,回查是 RocketMQ 事务消息对"生产者失联"的兜底机制,让半消息在没人给出结论时也能收敛,不会永久悬挂。
【三点】 第一,先说正常流程。生产者先发送半消息,Broker 落库但不投递给消费者;然后生产者执行本地事务,成功就 Commit,半消息转为可见;失败就 Rollback,Broker 删除半消息。第二,回查解决的是异常路径。如果生产者崩溃、超时或网络抖动,Broker 收不到 Commit 或 Rollback,就会主动调用生产者的回查回调,询问本地事务的真实状态。回查间隔是递增的,默认 60 秒起步,最大回查次数默认 15 次,避免高频回查把正在恢复的生产者打垮。第三,最终状态这样确定。回查回调返回 Commit 就投递消息,返回 Rollback 就删除半消息,返回 Unknown 就继续重试;达到最大回查次数仍无结论,Broker 按失败处理,删除半消息并转入死信队列,由人工介入。这里的关键是回查只能判断本地事务状态,所以业务方必须把事务状态表和业务表放在同一个本地事务里写入,否则回查没有可靠依据。
【边界】 当然,回查只解决生产者失联的问题,不解决消费者处理失败。消费端还是要靠幂等、重试和死信队列兜底,核心业务再叠加日终对账,才能保证最终一致。
题目:RocketMQ 事务消息为什么要设计回查?回查超时或多次失败后,消息的最终状态如何确定?
难度:medium
标签:arch/distributed/transaction, distributed/mq, distributed/rocketmq
评分:⭐⭐⭐☆☆(3/5)
练习次数:1
rocketmq事务消息的回查实际上是给事务消息流程中细节的补偿;
事务消息的过程是,生产者创建事务消息发送半消息给到broker,broker落库,然后等待生产者发送后续的执行结果,是本地执行成功的commit,让消费者看到半消息进行消费,还是本地执行失败,把半消息移除,结束事务消息;
这里需要broker从生产者获取实际执行情况,如果生产者一直不发送,broker没什么处理方法,这里就有了回查去处理这个问题,broker主动找生产者询问当前情况,并且周期递增性的去进行轮询,如果多次都无法获取结果,那么认定生产者出现问题,对应的也就认定事务消息失败了
评分:⭐⭐⭐☆☆(3/5)
优点:
不足:
补充:
完整讲解见上方「完整讲解(权威版)」