写点什么

分布式事务 - 消息队列实现分布式事务

作者:zarmnosaj
  • 2022-10-25
    四川
  • 本文字数:874 字

    阅读完需:约 3 分钟

消息队列实现分布式事务

除了 2PC 和 TCC 两种方案外,还有另一种实现分布式事务的方案,即使用消息队列实现数据最终一致性。


以下单扣减库存为案例说明:


  1. 订单服务和库存服务完成检查和预留资源,保证事务可以正常进行。

  2. 订单服务首先收到下单请求,在本地事务中完成添加订单表记录,同时往订单服务中的消息表中添加“减少库存任务消息”。本次请求结束。

  3. 订单服务由定时任务,异步读取订单服务的消息队列表,获取待发送的消息,发送给队列,为了通知库存服务执行减库存操作。

  4. 库存服务监听消息队列中扣减库存的消息,收到消息后就更新库存,并且在消息消费历史记录中记录消息,此举是为了为避免重复扣减库存,使消息被重复消费,并且在每次执行减库存之前,都需要查询是否存在对应的消息记录,已存在则说明执行过对应的消息,相当于保证了库存服务扣减库存操作的幂等性。

  5. 库存服务处理完成后,同步的向消息队列发送已完成减少库存的消息。

  6. 订单服务接收到完成库存减少的消息后,删除消息队列表中对应的库存更新任务消息。


注意:


在此方案中,每个环节出错,都有可能进行重试,所以要尽量保证消息消费的幂等性,假设订单在插入订单数据或者插入库存扣减消息时失败,则订单服务的本地事务会执行回滚;


如果扣减库存服务消息发送失败,或者库存服务未能成功接收消息,定时任务下次执行时会重新发送;


如果库存服务本地发生扣减异常,则会重新收到消息重新进行扣减库存;


如果库存服务在未完成扣减向队列发送已完成消息前,又再次收到了重复的消息扣减,则会由幂等性保证库存不会重复扣减;


如果库存服务在完成本地事务后,未能向消息队列中发送已完成,或者订单服务未能接收到消息,则再下一次由订单发送的消息扣减会触发库存服务的消息发送(此时不会再重复扣减库存)


由以上一系列的举例说明,可以看见此方案在多种方面都有异常处理机制,保证最后事务的完成,实现最终数据一致。

总结

此方案的优点:由消息中间件异步执行,协调事务,性能很高;逻辑繁琐度较低,不用考虑事务协调者的代码


缺点:虽然执行的性能很高,但是对表的读写会很频繁,其次是事务的执行时间相对较长,在高并发的场景下不适用。

发布于: 刚刚阅读数: 3
用户头像

zarmnosaj

关注

靡不有初,鲜克有终 2020-02-06 加入

成都后端

评论

发布
暂无评论
分布式事务-消息队列实现分布式事务_10月月更_zarmnosaj_InfoQ写作社区