一、事务消息的由来
1、案例
引用官方的购物案例:
小明购买一个100元的东西,账户扣款100元的同时需要保证在下游的积分系统给小明这个账号增加100积分。账号系统和积分系统是两个独立是系统,一个要减少100元,一个要增加100积分。如下图:
2、问题
账号服务扣款成功了,通知积分系统也成功了,但是积分增加的时候失败了,数据不一致了。
账号服务扣款成功了,但是通知积分系统失败了,所以积分不会增加,数据不一致了。
3、方案
RocketMQ针对第一个问题解决方案是:如果消费失败了,是会自动重试的,如果重试几次后还是消费失败,那么这种情况就需要人工解决了,比如放到死信队列里然后手动查原因进行处理等。
RocketMQ针对第二个问题解决方案是:如果你扣款成功了,但是往mq写消息的时候失败了,那么RocketMQ会进行回滚消息的操作,这时候我们也能回滚我们扣款的操作。
二、事务消息的原理
1、原理图解
2、详细过程
1.Producer发送半消息(Half Message)到broker。
我真想吐槽一句为啥叫半消息,难以理解,其实这就是prepare message,预发送消息。
Half Message发送成功后开始执行本地事务。
如果本地事务执行成功的话则返回commit,如果执行失败则返回rollback。(这个是在事务消息的回调方法里由开发者自己决定commit or rollback)
Producer发送上一步的commit还是rollback到broker,这里有两种情况:
1.如果broker收到了commit/rollback消息 :
如果收到了commit,则broker认为整个事务是没问题的,执行成功的。那么会下发消息给Consumer端消费。
如果收到了rollback,则broker认为本地事务执行失败了,broker将会删除Half Message,不下发给Consumer端。
2.如果broker未收到消息(如果执行本地事务突然宕机了,相当本地事务执行结果返回unknow,则和broker未收到确认消息的情况一样处理。):
broker会定时回查本地事务的执行结果:如果回查结果是本地事务已经执行则返回commit,若未执行,则返回rollback。
Producer端回查的结果发送给Broker。Broker接收到的如果是commit,则broker视为整个事务执行成功,如果是rollback,则broker视为本地事务执行失败,broker删除Half Message,不下发给consumer。如果broker未接收到回查的结果(或者查到的是unknow),则broker会定时进行重复回查,以确保查到最终的事务结果。重复回查的时间间隔和次数都可配。
共同学习,写下你的评论
评论加载中...
作者其他优质文章