前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用消息队列处理分布式事务

利用消息队列处理分布式事务

原创
作者头像
用户6884826
修改2021-07-08 14:39:48
9400
修改2021-07-08 14:39:48
举报
文章被收录于专栏:用户6884826的专栏

一.引言

这篇说说分布式事务的问题。企业现在的架构都由传统的架构转向了微服务架构,如下图所示:

file
file

那么,都不可避免的会遇到跨数据库调用的,分布式事务问题! 目前,业内解决分布式事务问题,都基本不用JTA这种强一致性的解决方案,基本是采用如下两套方案

基于TCC的事务框架 消息队列 OK,你们先记住两点 (1)图中的服务A和服务B,如果是同步调用,要求一起成功,或者一起失败,那么此时应选用TCC的事务框架,这点我改天另写一篇,先挖坑! (2)图中的服务A和服务B,如果是异步调用,比如服务C先调用服务A后,服务C不用管服务B的执行结果,直接返回,那么这种情况下,应选用消息队列!这篇文章重点讲! 目前为止,大部分文章都讲的太复杂了。导致很多新人看完后于是看这篇文章前,你们先忘记你们在其他文章看到的概念,跟着博主的思路走!

二.正文

先给大家套一个业务场景,也是很常见的一个异步调用场景: 支付宝往余额宝转钱

即将服务A假设为支付宝,服务B假设为余额宝。 于是呢,我们的支付宝往余额宝转100块钱是怎么做的呢? 特别容易,借助消息队列即可,如下图所示

file
file

一致性解决

OK,上面这一版有一个致命的问题!如下所示 事务开始 (1)给支付宝账户zhangsan,扣100元 (2)将(给余额宝账户zhangsan,加100元)封装为消息,发送给消息队列 事务结束 敢问你,如何保证第一步和第二步是在同一个事务里完成的。换句话说,第一步操作的是数据库,第二步操作的是一个消息队列,你如何保证这两步之间的一致性? 记住了,任何涉及到数据库和中间件之间的业务逻辑操作,都需要考虑二者之间的一致性。比如,你先操作了数据库,再操作缓存,数据库和缓存之间一致性如何解决?好吧,如果是博主的铁粉,应该知道怎么解决了,回到我们的场景。

改变思路,加一张事务表,如下图所示

file
file

注意了,此时事务的内容为 事务开始 (1)给支付宝账户zhangsan,扣100元 (2)给事件表插入一条记录 事务结束 此时是对同一数据库的两张表操作,因此可以用数据库的事务进行保证。 另外,起一个定时程序,定时扫描事务表,发现一个状态为’UNFINISHED’的事件,就进行封装为消息,发送到消息中间件,然后将状态改为’FINISHED’.

幂等性解决

注意了,这一版还存在一个幂等性问题! 仔细看,定时程序做了如下三个操作 (1)定时扫描事务表,发现一个状态为’UNFINISHED’的事件 (2)将事件信息,封装为消息,发送到消息中间件 (3)将事件状态改为’FINISHED’

OK,假设在步骤(2)的时候,发送完消息体,还未执行步骤(3),定时程序阵亡了!然后重启定时程序,发现刚那个事务的状态依然为’UNFINISHED’,因此重新发送。这样,就会出现重复消费问题。因此,幂等性也是需要保证的!

如果是博主的忠实读者,应该知道,博主曾经写过一篇《分布式之消息队列复习精讲》,里头就提到了如何解决幂等性问题。什么?你没看过这篇?拉出去枪毙! 借用这篇文章里的方案。在消费者端,也维护一个带主键的表,可以选txid为主键,如下图所示

file
file

如果一旦出现重复消费,则在事务里直接报出主键冲突错误,从而保证了幂等性!

面试连环炮 面试官:"你们用了微服务架构么?" 求职者:"用了,用了" 面试官:"怎么解决分布式事务的啊?" 求职者:"我们的服务刚好是异步的场景,所以用消息队列!" 面试官:"怎么保证一致性和幂等性啊?" 求职者:"嗯,听我细细说来….."

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.引言
  • 二.正文
    • 一致性解决
      • 幂等性解决
      相关产品与服务
      消息队列 CMQ 版
      消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档