下单扣库存 + 发送消息,如何保证两个操作的一致性?RocketMQ 的事务消息提供了一套优雅的解决方案。

一、分布式事务的诉求

  • 1.1 订单创建 + 发送”订单创建成功”消息的场景
  • 1.2 如果先创建订单后发消息——消息可能没发出去
  • 1.3 如果先发消息后创建订单——订单可能没创建成功

二、RocketMQ 事务消息的原理

  • 2.1 两阶段提交——发送 half 消息 → 执行本地事务 → 提交/回滚
  • 2.2 Half 消息——对消费者不可见
  • 2.3 事务状态回查——checkLocalTransaction()
  • 2.4 TransactionListener 接口——executeLocalTransaction() + checkLocalTransaction()
  • 2.5 事务消息的状态机——UNKNOW → COMMIT / ROLLBACK

三、完整代码实现

  • 3.1 TransactionMQProducer 的配置
  • 3.2 TransactionListener 实现
  • 3.3 本地事务执行 + 消息状态返回
  • 3.4 事务回查的实现——查订单表确认
  • 3.5 消费者端的幂等处理

四、事务消息 vs 本地消息表

  • 4.1 本地消息表的原理——同一数据库 + 定时任务
  • 4.2 本地消息表的优缺点
  • 4.3 RocketMQ 事务消息的优缺点
  • 4.4 选型决策——依赖的技术栈和场景复杂度

五、事务消息 vs Seata

  • 5.1 Seata AT 模式的原理
  • 5.2 适用场景的差异
  • 5.3 性能对比

六、生产环境注意事项

  • 6.1 事务回查的超时配置
  • 6.2 事务反查的幂等性
  • 6.3 事务消息的吞吐量——比普通消息低
  • 6.4 执行本地事务的耗时控制

七、总结

  • 事务消息的核心——half 消息保证最终一致性
  • 适用场景——异步解耦 + 数据一致性要求