基于RocketMQ的分布式事务是如何保证发送端和消费端的一致性的?
如图,这是RocketMQ的实现事务消息的流程图.大体步骤解读可以这样认为:
- 事务发起方首先发送prepare消息到MQ Server.
- MQ Server向事务发起方ACK确认消息发送成功.
- 事务发起方接收到确认消息后执行本地事务
- 事务发起方根据本地事务的执行结果返回commit或者rollback,从而想MQ Server提交二次确认. 如果执行结果是rollback,则MQ 将删除Prepare消息不进行下发; 如果是commit,则MQ将会吧消息发送给 消费端.
- 如果在执行本地事务过程中该应用挂掉或者超时,那么第4步提交的二次确认消息最终没有到达MQ Server, 则MQ Server将在经过一定时间后对消息发起消息回查,通过不停地询问同组的其他Prducer来获取状态.
- 发送方接收到回查消息后查询对应消息的本地事务执行结果.
- 根据回查得到的本地事务的最终执行结果再次提交二次确认.
- 消费端的消息成功机制则是有MQ保证的.
从以上流程可以看出,基于RocketMQ的分布式事务,消费端(Consumer)的成功是由MQ来保证的,如果消费端执行失败,或者抛出异常,MQ只能进行重试,怎么能保证 最终一致性呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这种方式本质还是通过消息队列的重试机制达到最终一致性的。
如果业务主动方执行本地事务成功,消息投递成功,但是业务被动房消费消息出现问题,会采用定时任务的方式,检查消息状态。对长时间处于“已发送”未变更状态为“已完成”的消息进行重新投递操作,这个扫描的时间要根据业务执行时间自行调整,比如:1min。
一般会有一个重试次数的限制。如果重试次数足够多之后仍然无法消费成功,必须通过工单、日志等方式进行人工干预让producer事务进行回退处理。
只能人工介入保证最终的一致性,自动回滚的可行性不高