高并发下分布式事务的解决方案-MQ消息事务+最终一致性

逃离Java 2018-06-20 14:21:20 ⋅ 142 阅读


分布式事务

分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。

分布式事务的应用场景

支付
一笔支付,是对买家账户进行扣款,同时对卖家账户进行加钱,这些操作必须在一个事务里执行,要么全部成功,要么全部失败。而对于买家账户属于买家中心,对应的是买家数据库,而卖家账户属于卖家中心,对应的是卖家数据库,对不同数据库的操作必然需要引入分布式事务。
在线下单
买家在电商平台下单,往往会涉及到两个动作,一个是扣库存,第二个是更新订单状态,库存和订单一般属于不同的数据库,需要使用分布式事务保证数据一致性。

消息事务+最终一致性

消息事务就是基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操作成功成功并且对外发消息成功,要么两者都失败,开源的RocketMQ就支持这一特性,具体原理如下:


1、A系统向消息中间件发送一条预备消息

2、消息中间件保存预备消息并返回成功

3、A执行本地事务

4、A发送提交消息给消息中间件
详细分析
步骤一出错,则整个事务失败,不会执行A的本地操作

步骤二出错,则整个事务失败,不会执行A的本地操作

步骤三出错,这时候需要回滚预备消息,怎么回滚?答案是A系统实现一个消息中间件的回调接口,消息中间件会去不断执行回调接口,检查A事务执行是否执行成功,如果失败则回滚预备消息

步骤四出错,这时候A的本地事务是成功的,那么消息中间件要回滚A吗?答案是不需要,其实通过回调接口,消息中间件能够检查到A执行成功了,这时候其实不需要A发提交消息了,消息中间件可以自己对消息进行提交,从而完成整个消息事务

基于消息中间件的两阶段提交往往用在高并发场景下,将一个分布式事务拆成一个消息事务(A系统的本地操作+发消息)+B系统的本地操作,其中B系统的操作由消息驱动,只要消息事务成功,那么A操作一定成功,消息也一定发出来了,这时候B会收到消息去执行本地操作,如果本地操作失败,消息会重投,直到B操作成功,这样就变相地实现了A与B的分布式事务。原理如下:


备注

虽然上面的方案能够完成A和B的操作,但是A和B并不是严格一致的,而是最终一致的,我们在这里牺牲了一致性,换来了性能的大幅度提升。当然,这种玩法也是有风险的,如果B一直执行不成功,那么一致性会被破坏,具体要不要玩,还是得看业务能够承担多少风险。

总结

分布式事务,本质上是对多个数据库的事务进行统一控制,按照控制力度可以分为:不控制、部分控制和完全控制。不控制就是不引入分布式事务,部分控制就是各种变种的两阶段提交。部分控制的好处是并发量和性能很好,缺点是数据一致性减弱了,完全控制则是牺牲了性能,保障了一致性,具体用哪种方式,最终还是取决于实际业务场景。

关注我们

可以关注“IT实战联盟”公众号并留言也可以加入交流群和作者互撩哦~~~


全部评论: 0

    我有话说:

    「轻阅读」分布式事务四种解决方案,成长需要尝试

    分布式事务事务操作位于不同节点上,需要保证事务 AICD 特性。

    「转载」分布式事务方案 - SAGA模式

    性能与架构:杜亦舒原文:https://mp.weixin.qq.com/s/An6QbAOw6jhWxg7GDT56Ug 本文目的是讲清楚 SAGA 这种分布式事务解决方案实现思路,不包括具体

    Java并发解决方案分布式应用限流实践

    任何限流都不是漫无目的,也不是一个开关就可以解决问题,常用限流算法有:令牌桶,漏桶。在之前文章中,也讲到过,但是那是基于单机场景来写。 之前文章:接口限流算法:漏桶算法&令牌桶算法

    「轻阅读」移动端事件穿透原理与解决方案

    本文将带你了解事件穿透及如何在实际项目中选择合适方案解决事件穿透问题。

    “12306”是如何支撑百万QPS

    ! 12306 抢票,极限并发带来思考 虽然现在...

    RocketMQ 分布式事务

    分布式事务先回顾一下事务,例如银行转账,A给B转100元,这个动作包括2个步骤:A账户减100元B账户加100......

    精品推荐:如何实现一个TCC分布式事务框架一点思考

    本文将以Spring容器为例,试图分析一下,实现一个通用TCC分布式事务框架需要注意一些问题。

    Nginx服务器高性能优化--轻松实现10万并发访问量

    作者:章为忠学架构https://www.toutiao.com/i6804346550882402828 前面讲了如何配置Nginx虚拟主机,如何配置服务日志等很多基础内容,大家可以去这里看看

    并发服务器逻辑处理瓶颈,如何解决

    从多方面入手解决并发服务器逻辑处理瓶颈

    分布式 NewSQL 数据库TiDB 3.1.0 版本发布,修复多项问题

    TiDB 是一款定位于在线事务处理/在线分析处理融合型数据库产品,实现了一键水平伸缩,强一致性多副本数据安全,分布式事务,实时 OLAP 等重要特性。

    Apache Traffic Control 5.1.2 发布,可扩分布式 CDN 解决方案

    Apache Traffic Control 5.1.2 现已发布。Apache Traffic Control 是一个分布式、可扩展冗余解决方案,实现了现代 CDN 所有核心功能,可

    BeetlSQL 3.1.0 发布,Spring Saga 事务支持

    本次发布增强了Saga在spring支持,使用kafka提供重试以及重试失败后放入丢弃队列里 Saga是用来在微服务中事务管理,具备ACID中ACD,不具备I,隔离性。在一定业务条件

    并发核心技术-幂等实现方案

    幂等性应该是合格程序员一个基因,在设计系统时,是首要考虑问题,尤其是在像支付宝,银行,互联网金融公司等涉及都是钱系统,既要高效,数据也要准确,所以不能出现多扣款,多打款等问题......

    消息队列常见问题(二):消息队列产生大量消息堆积怎么解决

    上一节列举了生产上消息队列产生大量消息堆积会有哪些后果,那相对应解决方法有哪些呢?1、消息被丢弃情况如果要实现防止消息过期问题,最好不要设置过期时间!那设置了过期时间导致消息丢失怎么补救呢?答案

    架构设计原则 - 并发

    并发设计可以从以下几方面考虑:无状态拆分服务化消息队列数据异构缓存并发化1. 无状态无状态应用容易进行水......

    BeetlSQL 3.0.10 发布,内置 sega 事务支持

    本次发布主要增加了分布式Sega事务支持,适合多数据源 按照社区建议,修改了了springboot yml配置方式 修改了@Jackson和@UpdateTime,本来是用来作为例子,但社区

    「轻阅读」消息总线(MQ)知多少

    消息总线(Message Queue,MQ),是一种跨进程通信机制,用于在上下游之间传递消息MQ是一种常见上下游“逻辑解耦+物理解耦”消息通信服务,消息发送上游只需要依赖MQ,逻辑上和物理上

    能够替代 Jenkins 13个解决方案,了解

    Jenkins 是目前最常用持续集成工具,拥有近 50% 市场份额,它还是很多技术团队第一个使用自动化工具。但是随着自动化领域持续发展,Jenkins 逐渐暴露出了一些问题,例如缺乏功能