比如更新db并发送消息,由下游继续处理任务。但是无法保证更新db与发送消息同时成功。
1. rocketmq先发一个半消息(Half Msg,类似一个 Prepare 操作),这个消息是不会投递给消费者的
【如果半消息发送失败,db未更新,整个操作失败,无影响】
2. 半消息发送成功后更新db
【半消息发送成功,但此时发生异常,生产者以为失败了不会更新db。由于broker存储半消息成功了,缺迟迟等不到后续提交操作,超时后broker会询问生产者此消息要如何处理,生产者查询db,然后给broker答复】
【若db更新失败,生产者告诉broker回滚半消息】
3. db成功后提交半消息,此时投递给消费者
【若db成功但提交半消息失败,broker等不到提交操作,会触发回查】
【如果回查发生异常或者回查仍然返回"未知",或回查失败,RocketMQ 稍后会重新调度,最多会回查 15 次】
可以看到,任何异常都在考虑之内。