(二)消息中间件RocketMQ解决分布式事物

在单库单系统中,不需要对事物进行特殊的处理,回滚即可。当一个大系统拆分多个子系统微服务之后,由于事物不支持跨系统处理,就有了分布式事物的问题。

解决分布式事物常见的方案有以下几种:

  1. 基于消息中间件解决,比较常用的方案,可靠性高,适合于对实时性要求不是很高的应用场景。
  2. TCC(try confirm cancel)事物补偿性方案,实时性高,个人理解为直接通过rpc交互,如发生异常或者业务不满足,直接通过rpc作数据还原请求,需要写好事物还原接口。
  3. 最大努力通知型方案,经典案例微信支付宝支付回调,需做好查重,保持幂等性。

 

幂等性

幂等性是对接口而言,接口的幂等性是指在多次调用的情况下,得到的结果都能保持一致,业务需求一致。查询接口天然幂等,赠删改都要借助其他来保证幂等性。

保证幂等性方案有两种,去重表和全局唯一id。

  • 去重表:在支付场景中,每个订单只能成功支付一次,可以建一张去重表,保存支付成功的订单信息,并且保证订单id唯一,外部服务请求支付订单时,首先在去重表中查询是否存在该订单,存在则不执行,典型的例如对接微信支付、支付宝支付、银企直连。
  • 全局唯一id:根据业务和内容生成对应的唯一id,存储起来,比如存储在redis,执行业务之前根据这个全局id判定是否已经处理过,唯一id可用业务记录的关键内容、时间戳、记录id、uuid等生成。

使用消息中间件RocketMQ解决分布式事物

  1. 系统A作为消息生产者Producer,A在执行本地事物前会向消息中间件RocketMQ投递一条消息,Mq保存该消息,并且消息状态为Prepared,不投递给下游消费者系统B;
  2. Mq发送确认消息至A,并且开始计时等待A的响应,若超时,Mq会不断向A发送消息确认;
  3. A收到确认应答之后开始执行本地事物;
  4. 如果A本地事物执行成功,则向Mq发送Commit请求,Mq收到请求后,便向B投递消息,B开始执行事物;
  5. 如果A本地事物执行失败,会向Mq发送Rollback请求,Mq收到Rollback后,会删除消息,不再向B投递消息,流程结束
  6. B收到消息后开始执行本地事物,并把执行结果反馈至Mq;
  7. 若反馈超时,Mq触发超时机制,Mq会不断向B重复投递消息,直到B成功消费消息,此时需要注意幂等性问题;,
  8. 若B成功执行本地事物,反馈Commit确认消息至Mq,Mq清除对应消息数据,分布式事物成功执行完
  9. 若B未成功执行事物或者业务不满足,反馈消费失败给Mq,此时,Mq会重新向B投递消费的消息,直到消费成功,当超过设定重试次数仍然失败,此时则需要人工处理

当B执行事物失败,为什么不回滚A的事物?

上述流程可知,当B开始执行事物时,代表A的事物成功的执行了,如果再去回滚A的事物,可能会出现以下问题,需要增加回滚事物的请求接口,无疑加大了系统的复杂度和开发成本,而且保证不了回滚事物接口的成功执行,原本一个问题变成了两个问题,会引起更多bug的可能性比较高,大成本解决小概率事件。

更加详细原理见转载https://www.jianshu.com/p/453c6e7ff81c

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值