分布式事务2

老生常谈——利用消息队列处理分布式事务

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

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

  • 基于TCC的事务框架
  • 消息队列

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

正文

先给大家套一个业务场景,也是很常见的一个异步调用场景:

  • 支付宝往余额宝转钱

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

一致性解决

OK,上面这一版有一个致命的问题!如下所示

事务开始
(1)给支付宝账户zhangsan,扣100元
(2)将(给余额宝账户zhangsan,加100元)封装为消息,发送给消息队列
事务结束

敢问你,如何保证第一步和第二步是在同一个事务里完成的。换句话说,第一步操作的是数据库,第二步操作的是一个消息队列,你如何保证这两步之间的一致性?
记住了,任何涉及到数据库和中间件之间的业务逻辑操作,都需要考虑二者之间的一致性。比如,你先操作了数据库,再操作缓存,数据库和缓存之间一致性如何解决?好吧,如果是博主的铁粉,应该知道怎么解决了,回到我们的场景。
改变思路,加一张事务表,如下图所示

注意了,此时事务的内容为

事务开始
(1)给支付宝账户zhangsan,扣100元
(2)给事件表插入一条记录
事务结束

此时是对同一数据库的两张表操作,因此可以用数据库的事务进行保证。
另外,起一个定时程序,定时扫描事务表,发现一个状态为‘UNFINISHED‘的事件,就进行封装为消息,发送到消息中间件,然后将状态改为‘FINISHED‘.

幂等性解决

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

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

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

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

面试连环炮

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

总结

这篇文章说了微服务架构下,异步服务之间的分布式事务是如何保证的。

原文地址:https://www.cnblogs.com/longxok/p/10932398.html

时间: 2024-10-10 03:24:57

分布式事务2的相关文章

XA分布式事务

XA分布式事务 XA XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准.目前,Oracle.Informix.DB2和Sybase等各大数据库厂家都提供对XA的支持.XA协议采用两阶段提交方式来管理分布式事务.XA接口提供资源管理器与事务管理器之间进行通信的标准接口.XA协议包括两套函数,以xa_开头的及以ax_开头的 简介编辑 取决于上下文, XA 有多种意思. 我们常见的数据库连接交易中的 XA 是指由 X/Open 组织提出的分布式交

浅谈分布式事务

前言应用场景 事务必须满足传统事务的特性,即原子性,一致性,分离性和持久性.但是分布式事务处理过程中, 某些场地比如在电商系统中,当有用户下单后,除了在订单表插入一条记录外,对应商品表的这个商品数量必须减1吧,怎么保证? 在搜索广告系统中,当用户点击某广告后,除了在点击事件表中增加一条记录外,还得去商家账户表中找到这个商家并扣除广告费吧,怎么保证? 一 本地事务以用户A转账用户B为例,假设有 用户A账户表:A(id,userId,amount) 用户B账户表:B(id,userId,amount

聊聊分布式事务

聊聊分布式事务 2017-04-15 数据库开发 (点击上方公众号,可快速关注) 作者:员海滨 nickid.cn/2017/04/分布式事务/ 如有好文章投稿,请点击 → 这里了解详情 分布式事务场景如何设计系统架构及解决数据一致性问题,个人理解最终方案把握以下原则就可以了,那就是:大事务=小事务(原子事务)+异步(消息通知),解决分布式事务的最好办法其实就是不考虑分布式事务,将一个大的业务进行拆分,整个大的业务流程,转化成若干个小的业务流程,然后通过设计补偿流程从而考虑最终一致性. 什么是事

使用事件和消息队列实现分布式事务(转+补充)

虽然本文并非笔者原创,但是我们在非强依赖的事务中原理上也是采用这种方式处理的,不过因为没有仔细去总结,最近在整理和总结时看到了,故转载并做部分根据我们实际情况的完善和补充. 不同于单一架构应用(Monolith), 分布式环境下, 进行事务操作将变得困难, 因为分布式环境通常会有多个数据源, 只用本地数据库事务难以保证多个数据源数据的一致性. 这种情况下, 可以使用两阶段或者三阶段提交协议来完成分布式事务.但是使用这种方式一般来说性能较差, 因为事务管理器需要在多个数据源之间进行多次等待. 有一

java分布式事务

原文地址:http://blog.csdn.net/moonpure/article/details/52779794 在本系列先前的文章中,我们主要讲解了JDBC对本地事务的处理,本篇文章将讲到一个分布式事务的例子. 请通过以下方式下载github源代码: git clone https://github.com/davenkin/jta-atomikos-hibernate-activemq.git 本地事务和分布式事务的区别在于:本地事务只用于处理单一数据源事务(比如单个数据库),分布式事

分布式事务 解决方案

事务的概念来源于业务过程.在许多情况下我们都希望能够确保在一个过程中执行的所有操作是完全成功的.在集中式系统中,事务被广泛用于服务器端和数据库系统,控制数据的操作.随着分布式计算的发展,事务在分布式计算领域中也得到了广泛的应用,但是分布式系统架构中,分布式事务问题是一个绕不过去的挑战.而微服务架构的流行,让分布式事问题日益突出! 下面我们以电商购物支付流程中,在各大参与者系统中可能会遇到分布式事务问题的场景进行详细的分析! 如上图所示,假设三大参与平台(电商平台.支付平台.银行)的系统都做了分布

关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究[转]

1.XA XA是由X/Open组织提出的分布式事务的规范.XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接口.XA接口是双向的系统接口,在事务管理器(Transaction Manager)以及一个或多个资源管理器(Resource Manager)之间形成通信桥梁.XA之所以需要引入事务管理器是因为,在分布式系统中,从理论上讲(参考Fischer等的论文),两台机器理论上无法达到一致的状态,需要引入一

本地事务和分布式事务工作实践 【转】

一:从事务的历史说起 知已知彼,百战不败.想了解事务,我们从事务的历史说起. 在Windows平台上,事务的概念最开始出现在关系型数据库中,但是随着.net平台的发展,事务包括的的范围也越来越宽,先一睹为快, 在关系型数据库中的事务是通过begin transaction,rollback transaction, commit 等关键字来实现事务的. BEGIN TRANSACTION  UPDATE [dbo].[T_ACCOUNT] SET BALANCE = BALANCE + @amo

【故障处理】分布式事务ORA-01591错误解决

[故障处理]分布式事务ORA-01591错误解决 1  BLOG文档结构图       2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 分布式事务的简单概念         ② ORA-01591错误解决   Tips: ① 本文在ITpub(http://blog.itpub.net/26736162).博客园(http://www.cnblogs.com/lhrbest)和微信公众号(x

对分布式事务、消息队列的重新认识

本质上问题可以抽象为:当一个表数据更新后,怎么保证另一个表的数据也必须要更新成功.若两张表在同一个数据库实例中,则使用本地事务就好了.否则可以采用分布式事务,或者消息队列. 前阵子从支付宝转账1万块钱到余额宝,这是日常生活的一件普通小事,但作为互联网研发人员的职业病,我就思考支付宝扣除1万之后,如果系统挂掉怎么办,这时余额宝账户并没有增加1万,数据就会出现不一致状况了. 上述场景在各个类型的系统中都能找到相似影子,比如在电商系统中,当有用户下单后,除了在订单表插入一条记录外,对应商品表的这个商品