MQ分布式事务处理流程

🛒 业务场景:用户下单购买商品

需求:用户下单成功 → 扣款成功 → 赠送积分,三个步骤必须全部成功或全部失败

涉及服务:订单服务、支付服务、积分服务

1
订单服务处理
📦 订单服务
本地事务:创建订单记录
订单ID: 12345
用户ID: 789
金额: ¥100
📨 消息队列
半消息状态
其他服务暂时看不到
💰 支付服务
等待中...
⭐ 积分服务
等待中...
关键步骤: 1. 发送半消息到MQ 2. 执行本地事务(插入订单) 3. 本地事务成功后,确认半消息 → 消息变为可见
⬇️
2
支付服务处理
📦 订单服务
已完成 ✅
📨 消息队列
消息可见
订单创建成功消息
新的半消息
支付处理消息
💰 支付服务
本地事务:记录支付信息
订单ID: 12345
支付状态: 成功
支付时间: 14:30
⭐ 积分服务
等待中...
关键步骤: 1. 消费订单消息 2. 发送新的半消息到MQ 3. 执行本地事务(记录支付) 4. 本地事务成功后,确认半消息
⬇️
3
积分服务处理
📦 订单服务
已完成 ✅
📨 消息队列
消息可见
支付成功消息
💰 支付服务
已完成 ✅
⭐ 积分服务
本地事务:增加用户积分
用户ID: 789
积分: +10
总积分: 150
关键步骤: 1. 消费支付成功消息 2. 执行本地事务(增加积分) 3. 整个分布式事务完成 🎉

🚨 异常情况处理与最终一致性

💡 关键理解:MQ事务 ≠ 数据库事务

MQ分布式事务保证的是最终一致性,不是强一致性回滚!

✅ 情况1:中间服务失败(可阻断)

场景:订单服务成功,但支付服务本地事务失败

结果:支付服务的半消息被丢弃,积分服务收不到消息,事务自然终止

处理流程:
订单已创建 → 支付失败 → 半消息丢弃 → 积分服务不执行 → 需要补偿订单

⚠️ 情况2:最后服务失败(需要补偿)

场景:订单、支付都成功,但积分服务失败

问题:前面的服务已经提交,无法自动回滚!

🔄 补偿策略(三选一)
方案1:重试机制
• 积分消息重新入队,多次重试
• 设置退避策略(1分钟、5分钟、30分钟...)
• 最大重试次数后转人工处理
方案2:补偿流程(Saga模式)
• 积分服务发送"补偿消息"
• 支付服务收到 → 执行退款
• 订单服务收到 → 取消订单
• 通知用户:订单处理失败,已退款
方案3:最终一致性
• 标记订单为"积分待处理"状态
• 后台任务定期检查并重试
• 用户可正常使用订单,积分稍后到账
• 系统维护数据最终一致

🎯 实际业务建议

适合MQ事务的场景:
• 可补偿的业务操作
• 容忍短时间不一致
• 异步处理需求
• 高并发场景
不适合的场景:
• 强一致性要求
• 不可补偿的操作
• 实时性要求极高
• 复杂的依赖关系
当前处理的服务
消息队列
半消息(不可见)
可见消息
本地事务