RocketMQ分布式事物

问题

我们看到在转账业务中,有两步,一个是操作用户A扣钱,一个是操作用户B加钱

如果在同一个数据库中进行,可以保证这两步操作,要么同时成功,要么同时不成功。这样就保证了转账的数据一致性。

但是如果用户A的数据在集群A中,用户B在集群B中呢?因为他们不在同一个事务中;如用户A扣款成功,但用户B加钱失败了;那就坑了,数据不完整了。

类似这种问题在微服务架构会更多,因为各个服务都是独立的模块,都是远程调用,都没法在同一个事务中,都会遇到事务问题。

消息中间件方案

在这里插入图片描述

RocketMQ事务方案

RocketMq消息中间件把消息分为两个阶段

Prepared阶段
该阶段主要发一个消息到rocketmq,但该消息只储存在commitlog中,但consumeQueue中不可见,也就是消费端(订阅端)无法看到此消息。

commit/rollback阶段(确认阶段)
该阶段主要是把prepared消息保存到consumeQueue中,即让消费端可以看到此消息,也就是可以消费此消息。

在这里插入图片描述
整个流程:
1、在扣款之前,先发送预备消息
2、发送预备消息成功后,执行本地扣款事务
3、扣款成功后,再发送确认消息
4、消息端(加钱业务)可以看到确认消息,消费此消息,进行加钱

异常场景:
异常1:如果发送预备消息失败,下面的流程不会走下去;这个是正常的
异常2:如果发送预备消息成功,但执行本地事务失败;这个也没有问题,因为此预备消息不会被消费端订阅到,消费端不会执行业务。
异常3:如果发送预备消息成功,执行本地事务成功,但发送确认消息失败;RocketMq会定时遍历commitlog中的预备消息,因为预备消息最终肯定会变为commit消息或Rollback消息,所以遍历预备消息去回查本地业务的执行状态,如果发现本地业务没有执行成功就rollBack,如果执行成功就发送commit消息。
异常4:如果发送预备消息成功,执行本地事务成功,发送确认消息成功,消费端失败;失败会一直重试,重试到一定次数不重试了那就发短信通知管理人员手动处理

消费端(加钱业务)需要考虑幂等设计

常用的方案是唯一键判重

参考文章:https://www.jianshu.com/p/286cac4625b6

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值