1、背景:
RockeyMQ
实现分布式事务(拿下单和扣减库存为例,如果下单和扣减库存在一个分布式系统中,需要维持一个事务性)
如果下单后发消息提示需要扣减库存,保持一个分布式事务的一致性,就会出现以下场景:
-
场景一:先下单后发消息
问题:先下单后如果消息发送失败,无法扣减库存业务无法订阅了此消息,但是却下了单;
-
场景二:先发消息后下单
问题:消息发送成功,但是下单失败,但是扣减库存的业务订阅了此消息,则扣减了库存却未下单。
RocketMQ
解决此问题的方法分为两个阶段:prepared
阶段和确认阶段(其中确认阶段分为Commit
和Rollback
,取决于事务是否执行成功)。
2、流程分析
prepared
阶段:主要发一个消息到Rocketmq
,但该消息只储存在commitlog
中,但consumeQueue
中不可见,也就是消费端(订阅端)无法看到此消息。
确认阶段:主要是把prepared
消息保存到consumeQueue
中,即让消费端可以看到此消息,也就是可以消费此消息。
上图说明了事务消息的大致方案,其中分为两种情况:正常事务消息的发送及提交、事务消息的补偿流程。
2.1、事务消息发送及提交
(1) 发送消息(half
消息);
(2) 服务端响应消息写入结果;
(3) 根据发送结果执行本地事务(如果写入失败,此时half
消息对业务不可见