RocketMQ事务机制
事务就是要保证一系列操作的一致性,同时成功或同时失败。
在单个JVM中,如果使用了Spring,我们只需要@Transactional注解就能开启事务了。
那么在一个分布式/微服务的系统下, 如何做事务机制呢?
RocketMQ事务消息
RocketMQ中有这样几个概念
- 半消息/准备消息
是指一个消息从生产者发送到消息队列,还没有被生产者进行消费二次确认前的消息。 发送者把事务消息标记为“暂时无法送达”。 - 消息状态检查
当网络断开或者生产者重启可能会导致事务消息二次确认的丢失。当MQ发现消息长时间处于半消息状态时,会向消息创建者发送请求,检查消息的最终状态(提交还是回滚)
事务消息的执行流程如下图
- 生产者发送半消息到MQ服务器
- 半消息发送成功后执行本地事务
- 根据本地消息的成功与否,向MQ服务器发送提交或者回滚消息
- 如果在执行本地事务期间,未显示提交/回滚,MQ服务器将向同一组中的每个生产者发送检查消息来获取事务最新状态
- 基于本地事务状态的生产者回复提交或回滚状态
- 已提交的消息传递给使用者,回滚的消息将被MQ服务器抛弃。
事务到这里就结束了
那么有同学可能就要问了, 如果消息提交, 但是消费者消费消息时失败了, 怎么办?
为什么消费者消费消息失败? 可能时连接超时,可能是消费出错。
第一种, 我们只要消息重试就可以了。
如果是第二种,第一要重新排查代码问题, 第二是要报警和提醒,由人工介入或者T+1补偿。 比如订单完成后,积分服务失败, 积分没有到账。