宇树Java面试被问:RocketMQ事务消息的二阶段提交实现
一、核心概念理解事务消息解决什么问题java复制下载// 分布式事务典型问题本地事务与消息发送的一致性 // 传统方式存在的问题 1. 先发消息后执行本地事务 → 消息发送成功但本地事务失败 2. 先执行本地事务后发消息 → 本地事务成功但消息发送失败RocketMQ事务消息的核心机制text复制下载Producer发送Half消息 → Broker存储Half消息 → 执行本地事务 ↓ Broker等待事务状态回查 ← Producer返回本地事务结果 ↓ 根据结果提交或回滚消息二、两阶段提交详细流程第一阶段发送Half消息java复制下载public class TransactionProducer { public static void main(String[] args) throws Exception { // 1. 创建事务消息生产者 TransactionMQProducer producer new TransactionMQProducer(TransactionProducerGroup); producer.setNamesrvAddr(127.0.0.1:9876); // 2. 设置事务监听器核心 producer.setTransactionListener(new TransactionListener() { /** * 执行本地事务 * param msg Half消息 * param arg 业务参数 * return 本地事务状态 */ Override public LocalTransactionState executeLocalTransaction(Message msg, Object arg) { try { // 执行本地数据库事务 boolean success doLocalBusinessTransaction(msg, arg); if (success) { System.out.println(本地事务执行成功提交消息); return LocalTransactionState.COMMIT_MESSAGE; } else { System.out.println(本地事务执行失败回滚消息); return LocalTransactionState.ROLLBACK_MESSAGE; } } catch (Exception e) { System.out.println(本地事务执行异常回查); return LocalTransactionState.UNKNOW; } } /** * 事务回查Broker主动查询事务状态 * param msg Half消息 * return 事务状态 */ Override public LocalTransactionState checkLocalTransaction(MessageExt msg) { // 根据业务ID查询本地事务状态 String transactionId msg.getTransactionId(); boolean status queryLocalTransactionStatus(transactionId); if (status) { System.out.println(事务回查本地事务已提交); return LocalTransactionState.COMMIT_MESSAGE; } else { System.out.println(事务回查本地事务已回滚); return LocalTransactionState.ROLLBACK_MESSAGE; } } }); // 3. 启动生产者 producer.start(); // 4. 发送事务消息 Message msg new Message(TransactionTopic, TagA, Order-001.getBytes(StandardCharsets.UTF_8)); // 设置事务ID关键 msg.setKeys(TXN- System.currentTimeMillis()); // 发送Half消息第一阶段 SendResult sendResult producer.sendMessageInTransaction(msg, // 业务参数会在executeLocalTransaction中传递 new BusinessParam(orderId, 123456, 100.00) ); System.out.println(Half消息发送结果: sendResult.getSendStatus()); } }篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】三、完整执行时序图text复制下载┌─────────┐ ┌────────┐ ┌────────┐ │ Producer│ │ Broker │ │ 本地DB │ └────┬────┘ └───┬────┘ └────┬───┘ │ 1.发送Half消息 │ │ │───────────────│ │ │ │ │ │ │ 2.存储Half消息 │ │ │───────────────│ │ │ │ │ 3.返回Half成功 │ │ │───────────────│ │ │ │ │ │ 4.执行本地事务 │ │ │────────────────────────────────│ │ │ │ │ 5.返回事务状态 │ │ │───────────────│ │ │ │ │ │ │6.提交/回滚消息 │ │ │───────────────│ │ │ │ │(可能)7.事务回查 │ │ │───────────────│ │ │ │ │ │ 8.返回回查结果 │ │ │───────────────│ │ │ │ │ │ │9.最终提交/回滚 │ │ │───────────────│四、关键配置参数yaml复制下载# Broker端配置 broker.conf: transactionCheckMax: 15 # 最大回查次数 transactionCheckInterval: 60000 # 回查间隔(ms) transactionTimeOut: 6000 # 超时时间(ms) # Producer端配置 producer: checkThreadPoolMinSize: 1 # 回查线程池最小 checkThreadPoolMaxSize: 1 # 回查线程池最大 checkRequestHoldMax: 2000 # 回查请求队列大小五、代码实现最佳实践1. 完整的订单事务示例java复制下载Service public class OrderTransactionService { Resource private OrderMapper orderMapper; Resource private TransactionMQProducer transactionMQProducer; /** * 创建订单事务消息 */ public void createOrderWithTransaction(OrderDTO orderDTO) { // 构建消息 Message msg new Message(ORDER_TOPIC, CREATE, JSON.toJSONBytes(orderDTO)); // 设置业务标识 msg.setKeys(ORDER_ orderDTO.getOrderNo()); msg.putUserProperty(businessType, ORDER_CREATE); // 发送事务消息 SendResult sendResult transactionMQProducer.sendMessageInTransaction( msg, new OrderTransactionArg(orderDTO) ); if (!sendResult.getSendStatus().equals(SendStatus.SEND_OK)) { throw new RuntimeException(Half消息发送失败); } } /** * 事务监听器实现 */ Component public class OrderTransactionListener implements TransactionListener { Override public LocalTransactionState executeLocalTransaction(Message msg, Object arg) { OrderTransactionArg transactionArg (OrderTransactionArg) arg; OrderDTO orderDTO transactionArg.getOrderDTO(); try { // 1. 保存订单到数据库 Order order convertToOrder(orderDTO); orderMapper.insert(order); // 2. 扣减库存调用库存服务 boolean deductResult inventoryService.deductStock( orderDTO.getProductId(), orderDTO.getQuantity() ); if (!deductResult) { // 库存不足回滚本地事务 orderMapper.deleteById(order.getId()); return LocalTransactionState.ROLLBACK_MESSAGE; } // 3. 记录事务日志用于回查 transactionLogService.saveTransactionLog( msg.getTransactionId(), ORDER_CREATE, order.getId(), LocalTransactionState.COMMIT_MESSAGE.name() ); return LocalTransactionState.COMMIT_MESSAGE; } catch (Exception e) { log.error(订单本地事务执行异常, e); // 记录异常状态 transactionLogService.saveTransactionLog( msg.getTransactionId(), ORDER_CREATE, null, LocalTransactionState.UNKNOW.name() ); return LocalTransactionState.UNKNOW; } } Override public LocalTransactionState checkLocalTransaction(MessageExt msg) { // 根据事务ID查询事务日志 String transactionId msg.getTransactionId(); TransactionLog log transactionLogService.getByTransactionId(transactionId); if (log null) { // 没有事务记录需要回滚 return LocalTransactionState.ROLLBACK_MESSAGE; } if (COMMIT_MESSAGE.equals(log.getStatus())) { // 事务已提交 return LocalTransactionState.COMMIT_MESSAGE; } else { // 事务需要回滚 return LocalTransactionState.ROLLBACK_MESSAGE; } } } /** * 事务参数封装 */ Data AllArgsConstructor public static class OrderTransactionArg { private OrderDTO orderDTO; } }2. 消费端幂等处理java复制下载Component RocketMQMessageListener( topic ORDER_TOPIC, consumerGroup ORDER_CONSUMER_GROUP ) public class OrderConsumer implements RocketMQListenerMessageExt { Override public void onMessage(MessageExt message) { // 1. 检查消息幂等性 String messageId message.getMsgId(); if (redisTemplate.hasKey(MSG_ messageId)) { log.info(消息已处理跳过: {}, messageId); return; } // 2. 解析消息 OrderDTO orderDTO JSON.parseObject(message.getBody(), OrderDTO.class); // 3. 业务处理 try { // 更新订单状态为已确认 orderService.confirmOrder(orderDTO.getOrderNo()); // 4. 记录已处理消息 redisTemplate.opsForValue().set( MSG_ messageId, PROCESSED, 1, TimeUnit.HOURS ); } catch (Exception e) { log.error(订单处理失败将重试, e); throw new RuntimeException(e); } } }六、面试问题回答要点问题RocketMQ事务消息如何实现二阶段提交回答结构概念解释RocketMQ事务消息通过二阶段提交保证分布式事务的最终一致性核心思想将本地事务和消息发送绑定通过Half消息和状态回查机制实现第一阶段Half消息阶段Producer发送Half消息到BrokerBroker存储但不对Consumer可见Half消息发送成功后执行本地事务本地事务执行结果返回给BrokerCOMMIT、ROLLBACK或UNKNOWN篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】​​​第二阶段状态确认阶段如果本地事务返回COMMIT/ROLLBACKBroker立即提交/回滚消息如果返回UNKNOWNBroker会发起事务状态回查Producer实现TransactionListener.checkLocalTransaction()进行状态查询关键机制事务状态回查解决网络超时或生产者宕机问题消息幂等性消费端需要处理重复消息超时机制超过配置时间未确认的消息会自动回滚代码示例java复制 下载// 简要展示核心代码结构 producer.setTransactionListener(new TransactionListener() { public LocalTransactionState executeLocalTransaction(...) { // 执行本地业务 } public LocalTransactionState checkLocalTransaction(...) { // 状态回查 } });适用场景订单创建通知库存支付成功发送通知任何需要保证本地事务和消息发送一致性的场景注意事项事务消息不支持定时和批量消息确保checkLocalTransaction方法的幂等性合理配置回查次数和间隔面试加分项提到最大努力通知型事务对比TCC、Saga等分布式事务方案强调消息幂等处理的重要性提及RocketMQ 4.3的事务消息优化这样的回答既展示了理论知识又体现了实际编码能力适合中高级Java岗位面试。

相关新闻

学术 PPT 别再 “堆文字”!虎贲等考 AI-PPT 让数据说话,答辩评委主动点头“

学术 PPT 别再 “堆文字”!虎贲等考 AI-PPT 让数据说话,答辩评委主动点头“

“熬 3 天做的答辩 PPT,被导师批‘像文献摘抄’”“数据图表歪歪扭扭,评委看不清核心结论”“逻辑断层,讲完自己都懵”—— 这是无数科研人做学术 PPT 的噩梦。传统 PPT 制作陷入 “文字堆砌、设计杂乱、重点模糊” 的怪圈,把学术…

2026/7/3 15:40:38 阅读更多 →
降重 + 去 AIGC 双 buff!虎贲等考 AI:论文告别 “机器味”,查重率直降 30%

降重 + 去 AIGC 双 buff!虎贲等考 AI:论文告别 “机器味”,查重率直降 30%

“查重率 38% 改到崩溃,AIGC 检测还标红”“AI 写的论文逻辑僵硬,导师一眼看穿”“降重后语句不通,反而被打回重写”—— 如今高校论文检测早已进入 “查重 AIGC 双校验” 时代,单纯换词调语序的笨办法彻底失效。很多同学陷入 “…

2026/7/2 21:27:49 阅读更多 →
Java基于Spring Boot+Vue的基于ECharts的电商零售可视化系统

Java基于Spring Boot+Vue的基于ECharts的电商零售可视化系统

这里写目录标题项目介绍系统实现截图技术栈介绍Spring Boot与Vue结合使用的优势Spring Boot的优点Vue的优点Spring Boot 框架结构解析Vue介绍系统执行流程Java语言介绍系统测试目的可行性分析核心代码详细视频演示源码获取所需该项目可以在最下面查看联系方式,为防止…

2026/7/3 15:40:42 阅读更多 →

最新新闻

Spring Cloud OpenFeign负载均衡算法深度解析:源码、可扩展性与面试题

Spring Cloud OpenFeign负载均衡算法深度解析:源码、可扩展性与面试题

本文深入剖析Spring Cloud OpenFeign的负载均衡机制,从核心组件架构、RoundRobin/Random/Weighted等算法源码、ServiceInstanceListSupplier装饰器模式的可扩展性设计,到自定义负载均衡实战,最后附带10道高频面试题及答案剖析,助你…

2026/7/3 16:26:33 阅读更多 →
直流电机静音控制方案设计与实现

直流电机静音控制方案设计与实现

1. 项目概述:直流电机静音控制方案设计 在工业自动化和消费电子领域,直流电机的噪声问题一直是工程师面临的常见挑战。传统PWM控制方式虽然简单高效,但开关噪声和电磁干扰问题尤为突出。本项目采用东芝TB9051FTG电机驱动IC搭配德州仪器TM4C12…

2026/7/3 16:26:33 阅读更多 →
基于STM32单片机宠物自动喂食系统喂水控制系统 WIFI监控宠物喂养1(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)

基于STM32单片机宠物自动喂食系统喂水控制系统 WIFI监控宠物喂养1(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)

基于STM32单片机宠物自动喂食系统喂水控制系统 WIFI监控宠物喂养1(设计源文件万字报告讲解)(支持资料、图片参考_降重降ai) 版本0 :5个定时喂食喂食提醒自动/手动模式TFT液晶显示年,月,日,十,分…

2026/7/3 16:24:33 阅读更多 →
ICM-42688-P运动传感器与PIC18F4455在工业自动化中的应用

ICM-42688-P运动传感器与PIC18F4455在工业自动化中的应用

1. ICM-42688-P运动传感器的技术解析 ICM-42688-P是一款六轴运动传感器,集成了三轴陀螺仪和三轴加速度计。这款传感器在工业应用中表现出色,主要得益于以下几个关键技术特性: 1.1 高精度运动检测能力 ICM-42688-P的陀螺仪量程可达2000dps&a…

2026/7/3 16:24:33 阅读更多 →
STM32G031K8与KMX62 IMU在运动控制中的实践应用

STM32G031K8与KMX62 IMU在运动控制中的实践应用

1. 项目背景与核心价值在工业自动化、机器人技术和消费电子领域,稳定性和平衡控制一直是关键挑战。传统方案往往采用分立式传感器搭配复杂算法,不仅成本高企,调试周期也漫长。KMX62作为一款6自由度(6DOF)惯性测量单元(IMU),结合ST…

2026/7/3 16:22:33 阅读更多 →
零售收款机安全漏洞深度解析与实战加固指南

零售收款机安全漏洞深度解析与实战加固指南

1. 项目概述:为什么收款机安全不容忽视你可能觉得,一台小小的收款机,不就是收个钱、打个单吗?能有什么大不了的漏洞?我干了十几年零售和餐饮系统的技术运维,见过太多因为忽视收款机安全而“翻车”的案例。从…

2026/7/3 16:22:33 阅读更多 →

日新闻

Nginx防御TLS重协商攻击实战:从原理到配置与监控

Nginx防御TLS重协商攻击实战:从原理到配置与监控

1. 项目概述:为什么TLS重协商攻击至今仍需警惕十多年前的CVE-2011-1473,一个关于TLS/SSL协议重协商机制的漏洞,现在提起来还有必要吗?很多运维和开发朋友可能会觉得,这都老掉牙了,现代服务器和客户端不都默…

2026/7/3 0:03:59 阅读更多 →
华为防火墙双通道远程管理实战:Web与SSH配置详解

华为防火墙双通道远程管理实战:Web与SSH配置详解

1. 项目概述:为什么需要双通道远程管理防火墙?在任何一个稍具规模的企业网络里,防火墙都是那个默默守护在边界的关键角色。作为网络工程师,我们不可能每次都跑到机房,插上console线去配置它。远程管理能力,…

2026/7/3 0:03:59 阅读更多 →
AD74413R与PIC18F65K40的高精度工业数据采集方案

AD74413R与PIC18F65K40的高精度工业数据采集方案

1. 项目概述:AD74413R与PIC18F65K40的协同工作在工业自动化和精密测量领域,同时实现高精度模数转换(ADC)和数模转换(DAC)功能是许多复杂系统的核心需求。AD74413R作为一款四通道可配置模拟输入/输出器件,与PIC18F65K40微控制器的组合&#xf…

2026/7/3 0:05:59 阅读更多 →

周新闻

月新闻