基于RocketMQ的分布式事务是如何保证发送端和消费端的一致性的?

新手上路,请多包涵

preview
如图,这是RocketMQ的实现事务消息的流程图.大体步骤解读可以这样认为:

  1. 事务发起方首先发送prepare消息到MQ Server.
  2. MQ Server向事务发起方ACK确认消息发送成功.
  3. 事务发起方接收到确认消息后执行本地事务
  4. 事务发起方根据本地事务的执行结果返回commit或者rollback,从而想MQ Server提交二次确认. 如果执行结果是rollback,则MQ 将删除Prepare消息不进行下发; 如果是commit,则MQ将会吧消息发送给 消费端.
  5. 如果在执行本地事务过程中该应用挂掉或者超时,那么第4步提交的二次确认消息最终没有到达MQ Server, 则MQ Server将在经过一定时间后对消息发起消息回查,通过不停地询问同组的其他Prducer来获取状态.
  6. 发送方接收到回查消息后查询对应消息的本地事务执行结果.
  7. 根据回查得到的本地事务的最终执行结果再次提交二次确认.
  8. 消费端的消息成功机制则是有MQ保证的.

从以上流程可以看出,基于RocketMQ的分布式事务,消费端(Consumer)的成功是由MQ来保证的,如果消费端执行失败,或者抛出异常,MQ只能进行重试,怎么能保证 最终一致性呢?

阅读 3.6k
2 个回答

这种方式本质还是通过消息队列的重试机制达到最终一致性的。
如果业务主动方执行本地事务成功,消息投递成功,但是业务被动房消费消息出现问题,会采用定时任务的方式,检查消息状态。对长时间处于“已发送”未变更状态为“已完成”的消息进行重新投递操作,这个扫描的时间要根据业务执行时间自行调整,比如:1min。
一般会有一个重试次数的限制。如果重试次数足够多之后仍然无法消费成功,必须通过工单、日志等方式进行人工干预让producer事务进行回退处理。

只能人工介入保证最终的一致性,自动回滚的可行性不高

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题