精华内容
下载资源
问答
  • 分布式事务一致性
    2022-03-25 15:54:16

    分布式事务一致性框架:核心解决我们在实际系统中产生夸事务导致分布式事务问题。
    核心靠的就是最终一致性:rocketmq事务消息、rabbitmq补单、lcn、seata等。

    分式系统一致性算法:解决我们系统之间集群之后每个节点保持数据的一致性
    有那些:raft(nacos)、zab(zookeeper)、paxos等。


     

    【尚学堂】Java300集零基础适合初学者视频教程_Java300集零基础教程_Java初学入门视频基础巩固教程_Java语言入门到精通_哔哩哔哩_bilibili

    更多相关内容
  • Seata-AT如何保证分布式事务一致性.pdf
  • 分布式事务一致性

    千次阅读 2018-05-25 17:18:45
    有人的地方,就有江湖有江湖的地方,就有纷争问题的起源在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性? 具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,...

    有人的地方,就有江湖

    有江湖的地方,就有纷争

    问题的起源

    在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性? 

    具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,需要满足要么同时成功;要么同时失败。A、B、C 可能是多个不同部门开发、部署在不同服务器上的远程服务。

    在分布式系统来说,如果不想牺牲一致性,CAP 理论告诉我们只能放弃可用性,这显然不能接受。为了便于讨论问题,先简单介绍下数据一致性的基础理论。

    强一致

    当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据 CAP 理论,这种实现需要牺牲可用性。

    弱一致性

    系统并不保证续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。

    最终一致性

    弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS 是一个典型的最终一致性系统。

    在工程实践上,为了保障系统的可用性,互联网系统大多将强一致性需求转换成最终一致性的需求,并通过系统执行幂等性的保证,保证数据的最终一致性。但在电商等场景中,对于数据一致性的解决方法和常见的互联网系统(如 MySQL 主从同步)又有一定区别,群友的讨论分成以下 6 种解决方案。

    1. 规避分布式事务——业务整合

    业务整合方案主要采用将接口整合到本地执行的方法。拿问题场景来说,则可以将服务 A、B、C 整合为一个服务 D 给业务,这个服务 D 再通过转换为本地事务的方式,比如服务 D 包含本地服务和服务 E,而服务 E 是本地服务 A ~ C 的整合。

    优点:解决(规避)了分布式事务。

    缺点:显而易见,把本来规划拆分好的业务,又耦合到了一起,业务职责不清晰,不利于维护。

    由于这个方法存在明显缺点,通常不建议使用。

    2. 经典方案 - eBay 模式

    此方案的核心是将需要分布式处理的任务通过消息日志的方式来异步执行。消息日志可以存储到本地文本、数据库或消息队列,再通过业务规则自动或人工发起重试。人工重试更多的是应用于支付场景,通过对账系统对事后问题的处理。

    消息日志方案的核心是保证服务接口的幂等性。

    考虑到网络通讯失败、数据丢包等原因,如果接口不能保证幂等性,数据的唯一性将很难保证。

    eBay 方式的主要思路如下。

    Base:一种 Acid 的替代方案

    此方案是 eBay 的架构师 Dan Pritchett 在 2008 年发表给 ACM 的文章,是一篇解释 BASE 原则,或者说最终一致性的经典文章。文中讨论了 BASE 与 ACID 原则在保证数据一致性的基本差异。

    如果 ACID 为分区的数据库提供一致性的选择,那么如何实现可用性呢?答案是

    BASE (basically available, soft state, eventually consistent)

    BASE 的可用性是通过支持局部故障而不是系统全局故障来实现的。下面是一个简单的例子:如果将用户分区在 5 个数据库服务器上,BASE 设计鼓励类似的处理方式,一个用户数据库的故障只影响这台特定主机那 20% 的用户。这里不涉及任何魔法,不过它确实可以带来更高的可感知的系统可用性。

    文章中描述了一个最常见的场景,如果产生了一笔交易,需要在交易表增加记录,同时还要修改用户表的金额。这两个表属于不同的远程服务,所以就涉及到分布式事务一致性的问题。

    文中提出了一个经典的解决方法,将主要修改操作以及更新用户表的消息放在一个本地事务来完成。同时为了避免重复消费用户表消息带来的问题,达到多次重试的幂等性,增加一个更新记录表 updates_applied 来记录已经处理过的消息。

    系统的执行伪代码如下

    (点击可全屏缩放图片)

    基于以上方法,在第一阶段,通过本地的数据库的事务保障,增加了 transaction 表及消息队列 。

    在第二阶段,分别读出消息队列(但不删除),通过判断更新记录表 updates_applied 来检测相关记录是否被执行,未被执行的记录会修改 user 表,然后增加一条操作记录到 updates_applied,事务执行成功之后再删除队列。

    通过以上方法,达到了分布式系统的最终一致性。进一步了解 eBay 的方案可以参考文末链接。

    3. 去哪儿网分布式事务方案

    随着业务规模不断地扩大,电商网站一般都要面临拆分之路。就是将原来一个单体应用拆分成多个不同职责的子系统。比如以前可能将面向用户、客户和运营的功能都放在一个系统里,现在拆分为订单中心、代理商管理、运营系统、报价中心、库存管理等多个子系统。

    拆分首先要面临的是什么呢?

    最开始的单体应用所有功能都在一起,存储也在一起。比如运营要取消某个订单,那直接去更新订单表状态,然后更新库存表就 ok 了。因为是单体应用,库在一起,这些都可以在一个事务里,由关系数据库来保证一致性。

    但拆分之后就不同了,不同的子系统都有自己的存储。比如订单中心就只管理自己的订单库,而库存管理也有自己的库。那么运营系统取消订单的时候就是通过接口调用等方式来调用订单中心和库存管理的服务了,而不是直接去操作库。这就涉及一个『分布式事务』的问题。 

    分布式事务有两种解决方式

    1. 优先使用异步消息。

    上文已经说过,使用异步消息 Consumer 端需要实现幂等。

    幂等有两种方式,一种方式是业务逻辑保证幂等。比如接到支付成功的消息订单状态变成支付完成,如果当前状态是支付完成,则再收到一个支付成功的消息则说明消息重复了,直接作为消息成功处理。

    另外一种方式如果业务逻辑无法保证幂等,则要增加一个去重表或者类似的实现。对于 producer 端在业务数据库的同实例上放一个消息库,发消息和业务操作在同一个本地事务里。发消息的时候消息并不立即发出,而是向消息库插入一条消息记录,然后在事务提交的时候再异步将消息发出,发送消息如果成功则将消息库里的消息删除,如果遇到消息队列服务异常或网络问题,消息没有成功发出那么消息就留在这里了,会有另外一个服务不断地将这些消息扫出重新发送。

    2. 有的业务不适合异步消息的方式,事务的各个参与方都需要同步的得到结果。这种情况的实现方式其实和上面类似,每个参与方的本地业务库的同实例上面放一个事务记录库。

    比如 A 同步调用 B,C。A 本地事务成功的时候更新本地事务记录状态,B 和 C 同样。如果有一次 A 调用 B 失败了,这个失败可能是 B 真的失败了,也可能是调用超时,实际 B 成功。则由一个中心服务对比三方的事务记录表,做一个最终决定。假设现在三方的事务记录是 A 成功,B 失败,C 成功。那么最终决定有两种方式,根据具体场景:

    1. 重试 B,直到 B 成功,事务记录表里记录了各项调用参数等信息;

    2. 执行 A 和 B 的补偿操作(一种可行的补偿方式是回滚)。

    对 b 场景做一个特殊说明:比如 B 是扣库存服务,在第一次调用的时候因为某种原因失败了,但是重试的时候库存已经变为 0,无法重试成功,这个时候只有回滚 A 和 C 了。

    那么可能有人觉得在业务库的同实例里放消息库或事务记录库,会对业务侵入,业务还要关心这个库,是否一个合理的设计?

    实际上可以依靠运维的手段来简化开发的侵入,我们的方法是让 DBA 在公司所有 MySQL 实例上预初始化这个库,通过框架层(消息的客户端或事务 RPC 框架)透明的在背后操作这个库,业务开发人员只需要关心自己的业务逻辑,不需要直接访问这个库。

    总结起来,其实两种方式的根本原理是类似的,也就是将分布式事务转换为多个本地事务,然后依靠重试等方式达到最终一致性

    4. 蘑菇街交易创建过程中的分布式一致性方案

    交易创建的一般性流程

    我们把交易创建流程抽象出一系列可扩展的功能点,每个功能点都可以有多个实现(具体的实现之间有组合/互斥关系)。把各个功能点按照一定流程串起来,就完成了交易创建的过程。 

    面临的问题

    每个功能点的实现都可能会依赖外部服务。那么如何保证各个服务之间的数据是一致的呢?比如锁定优惠券服务调用超时了,不能确定到底有没有锁券成功,该如何处理?再比如锁券成功了,但是扣减库存失败了,该如何处理?

    方案选型

    服务依赖过多,会带来管理复杂性增加和稳定性风险增大的问题。试想如果我们强依赖 10 个服务,9 个都执行成功了,最后一个执行失败了,那么是不是前面 9 个都要回滚掉?这个成本还是非常高的。

    所以在拆分大的流程为多个小的本地事务的前提下,对于非实时、非强一致性的关联业务写入,在本地事务执行成功后,我们选择发消息通知、关联事务异步化执行的方案。

    消息通知往往不能保证 100% 成功;且消息通知后,接收方业务是否能执行成功还是未知数。前者问题可以通过重试解决;后者可以选用事务消息来保证。

    但是事务消息框架本身会给业务代码带来侵入性和复杂性,所以我们选择基于 DB 事件变化通知到 MQ 的方式做系统间解耦,通过订阅方消费 MQ 消息时的 ACK 机制,保证消息一定消费成功,达到最终一致性。由于消息可能会被重发,消息订阅方业务逻辑处理要做好幂等保证。

    所以目前只剩下需要实时同步做、有强一致性要求的业务场景了。在交易创建过程中,锁券和扣减库存是这样的两个典型场景。

    要保证多个系统间数据一致,乍一看,必须要引入分布式事务框架才能解决。但引入非常重的类似二阶段提交分布式事务框架会带来复杂性的急剧上升;在电商领域,绝对的强一致是过于理想化的,我们可以选择准实时的最终一致性。

    我们在交易创建流程中,首先创建一个不可见订单,然后在同步调用锁券和扣减库存时,针对调用异常(失败或者超时),发出废单消息到MQ。如果消息发送失败,本地会做时间阶梯式的异步重试;优惠券系统和库存系统收到消息后,会进行判断是否需要做业务回滚,这样就准实时地保证了多个本地事务的最终一致性。

     5. 支付宝及蚂蚁金融云的分布式服务 DTS 方案

    业界常用的还有支付宝的一种 xts 方案,由支付宝在 2PC 的基础上改进而来。主要思路如下,大部分信息引用自官方网站。

    分布式事务服务简介

    分布式事务服务 (Distributed Transaction Service, DTS) 是一个分布式事务框架,用来保障在大规模分布式环境下事务的最终一致性。DTS 从架构上分为 xts-client 和 xts-server 两部分,前者是一个嵌入客户端应用的 JAR 包,主要负责事务数据的写入和处理;后者是一个独立的系统,主要负责异常事务的恢复。

    核心特性

    传统关系型数据库的事务模型必须遵守 ACID 原则。在单数据库模式下,ACID 模型能有效保障数据的完整性,但是在大规模分布式环境下,一个业务往往会跨越多个数据库,如何保证这多个数据库之间的数据一致性,需要其他行之有效的策略。在 JavaEE 规范中使用 2PC (2 Phase Commit, 两阶段提交) 来处理跨 DB 环境下的事务问题,但是 2PC 是反可伸缩模式,也就是说,在事务处理过程中,参与者需要一直持有资源直到整个分布式事务结束。这样,当业务规模达到千万级以上时,2PC 的局限性就越来越明显,系统可伸缩性会变得很差。基于此,我们采用 BASE 的思想实现了一套类似 2PC 的分布式事务方案,这就是 DTS。DTS在充分保障分布式环境下高可用性、高可靠性的同时兼顾数据一致性的要求,其最大的特点是保证数据最终一致 (Eventually consistent)。

    简单的说,DTS 框架有如下特性:

    • 最终一致:事务处理过程中,会有短暂不一致的情况,但通过恢复系统,可以让事务的数据达到最终一致的目标。

    • 协议简单:DTS 定义了类似 2PC 的标准两阶段接口,业务系统只需要实现对应的接口就可以使用 DTS 的事务功能。

    • 与 RPC 服务协议无关:在 SOA 架构下,一个或多个 DB 操作往往被包装成一个一个的 Service,Service 与 Service 之间通过 RPC 协议通信。DTS 框架构建在 SOA 架构上,与底层协议无关。

    • 与底层事务实现无关: DTS 是一个抽象的基于 Service 层的概念,与底层事务实现无关,也就是说在 DTS 的范围内,无论是关系型数据库 MySQL,Oracle,还是 KV 存储 MemCache,或者列存数据库 HBase,只要将对其的操作包装成 DTS 的参与者,就可以接入到 DTS 事务范围内。

    以下是分布式事务框架的流程图 


    实现

    1. 一个完整的业务活动由一个主业务服务与若干从业务服务组成。

    2. 主业务服务负责发起并完成整个业务活动。

    3. 从业务服务提供 TCC 型业务操作。

    4. 业务活动管理器控制业务活动的一致性,它登记业务活动中的操作,并在活动提交时确认所有的两阶段事务的 confirm 操作,在业务活动取消时调用所有两阶段事务的 cancel 操作。”

    与 2PC 协议比较

    1. 没有单独的 Prepare 阶段,降低协议成本

    2. 系统故障容忍度高,恢复简单

    6. 农信网数据一致性方案

    1. 电商业务

    公司的支付部门,通过接入其它第三方支付系统来提供支付服务给业务部门,支付服务是一个基于 Dubbo 的 RPC 服务。

    对于业务部门来说,电商部门的订单支付,需要调用

    1. 支付平台的支付接口来处理订单;

    2. 同时需要调用积分中心的接口,按照业务规则,给用户增加积分。

    从业务规则上需要同时保证业务数据的实时性和一致性,也就是支付成功必须加积分。

    我们采用的方式是同步调用,首先处理本地事务业务。考虑到积分业务比较单一且业务影响低于支付,由积分平台提供增加与回撤接口。

    具体的流程是先调用积分平台增加用户积分,再调用支付平台进行支付处理,如果处理失败,catch 方法调用积分平台的回撤方法,将本次处理的积分订单回撤。

    (点击图片可以全屏缩放)

    2. 用户信息变更

    公司的用户信息,统一由用户中心维护,而用户信息的变更需要同步给各业务子系统,业务子系统再根据变更内容,处理各自业务。用户中心作为 MQ 的 producer,添加通知给 MQ。APP Server 订阅该消息,同步本地数据信息,再处理相关业务比如 APP 退出下线等。

    我们采用异步消息通知机制,目前主要使用 ActiveMQ,基于 Virtual Topic 的订阅方式,保证单个业务集群订阅的单次消费。

    总结

    分布式服务对衍生的配套系统要求比较多,特别是我们基于消息、日志的最终一致性方案,需要考虑消息的积压、消费情况、监控、报警等。

    参考资料

    • Base: An Acid Alternative (eBay 方案)

    In partitioned databases, trading some consistency for availability can lead to dramatic improvements in scalability.

    英文版 : http://queue.acm.org/detail.cfm?id=1394128 

    中文版: http://article.yeeyan.org/view/167444/125572 

    感谢李玉福、余昭辉、蘑菇街七公提供方案,其他多位群成员对本文内容亦有贡献。

    本文编辑李玉福、Tim Yang,转载请注明来自@高可用架构​​​​

    展开全文
  • 3、分布式事务一致性:本质上来说,分布式事务就是为了保证在分布式场景下,数据操作的正确执行。但分布式事务不像本地事务,可以做到ACID,分布式事务做不到。比如分布式存储场景下,一个存储

    关于各种一致性的理解:
    1、数据一致性,往往指的是缓存和数据库的一致性。

    2、事务的一致性,和原子性类似,都是从一个状态变到另一个状态,但不同的是,原子性追求这个过程不能出错,不论结果对不对,不能出错。但一致性更追求结果一致,比如A减少100,B增加100,这是一致的。当A减少100,B增加60,这是原子的,但不是一致的。

    3、分布式事务的一致性:本质上来说,分布式事务就是为了保证在分布式场景下,数据操作的正确执行。但分布式事务不像本地事务,可以做到ACID,分布式事务做不到。比如分布式存储场景下,一个存储节点通过本地事务减少100,不能同时保证另一个存储节点事务增加100,这实际上就是数据不一致。而在本地事务中,是可以做到的,本地事务把减100和加100当作一个原子操作来执行。
    但是分布式事务也是可以解决这一类问题的,但从而带来了很高的代价,也就是我们说的CAP理论,P分区容错是一定的。那么当C很强时,也就是强一致性的时候,也就是说用户访问任何一台数据库服务器,必须都是要数据一致的,第一个存储节点减少100,另一个存储节点必须增加100,这就是强一致性,但是问题是有网络延迟,第一个节点减少了100,第二个还没来得及加100,此时用户要访问第二台数据库服务器,怎么办? 那就不让他访问,也就是吸收Availability可用性。那如果要保证可用性怎么办?那就牺牲一致性,数据不一致没关系,最终一致就可以了。

    那解决这样的问题的框架有哪些?比如seata的AT,TCC等,就是实现全局事务的统一提交,要么就不提交,那这样就能保证所有数据的一致了。但当全局事务没有统一提交的时候,可能用户的请求查数据库,可能查到的还是旧数据。

    4、分布式事务的原子性:单个分枝事务成功,但其他事务可能失败,需要全局回滚。

    5、注意:CAP理论强调的是说在分布式存储系统中的。

    以上纯属个人理解,有问题请指出探讨。

    参考:https://blog.csdn.net/yeyazhishang/article/details/80758354
    参考:https://segmentfault.com/a/1190000040321750
    参考:http://www.dockone.io/article/9804

    展开全文
  • Seata-AT如何保证分布式事务一致性

    千次阅读 2020-12-16 20:14:15
    Seata-AT如何保证分布式事务一致性 Seata 是一款开源的分布式事务解决方案,star高达18100+,社区活跃度极高,致力于在微服务架构下提供高性能和简单易用的分布式事务服务,本文将剖析Seata-AT的实现原理,让用户对AT...

    Seata-AT如何保证分布式事务一致性

    Seata 是一款开源的分布式事务解决方案,star高达18100+,社区活跃度极高,致力于在微服务架构下提供高性能和简单易用的分布式事务服务,本文将剖析Seata-AT的实现原理,让用户对AT模式有更深入的认识.
    作者:陈健斌(funkye) github id: a364176773

    目录

    1. Seata 事务模式是什么?
    2. AT模式是什么?
    3. AT如何保证分布式事务一致性?
    4. Seata近期规划;
    5. 总结;

    Seata事务模式是什么?

    1.1Seata对事务的定义

    Seata 定义了全局事务的框架。
    全局事务 定义为若干 分支事务 的整体协调:
    1.TM 向 TC 请求发起(Begin)、提交(Commit)、回滚(Rollback)全局事务。
    2.TM 把代表全局事务的 XID 绑定到分支事务上。
    3.RM 向 TC 注册,把分支事务关联到 XID 代表的全局事务中。
    4.RM 把分支事务的执行结果上报给 TC。(可选)
    5.TC 发送分支提交(Branch Commit)或分支回滚(Branch Rollback)命令给 RM。

    img

    Seata 的 全局事务 处理过程,分为两个阶段:
    执行阶段 :执行 分支事务,并 保证 执行结果满足是 可回滚的(Rollbackable) 和 持久化的(Durable)。
    完成阶段: 根据 执行阶段 结果形成的决议,应用通过 TM 发出的全局提交或回滚的请求给 TC,
    TC 命令 RM 驱动 分支事务 进行 Commit 或 Rollback。
    Seata 的所谓 事务模式 是指:运行在 Seata 全局事务框架下的 分支事务 的行为模式。
    准确地讲,应该叫作 分支事务模式。
    不同的 事务模式 区别在于 分支事务 使用不同的方式达到全局事务两个阶段的目标。
    即,回答以下两个问题:
    执行阶段 :如何执行并 保证 执行结果满足是 可回滚的(Rollbackable) 和 持久化的(Durable)。
    完成阶段: 收到 TC 的命令后,做到事务的回滚/提交

    1.2 其它二阶段事务如何在Seata事务框架下运转

    1.2.1 TCC事务模式

    首先,我们先来看下TCC事务是如何融合在Seata事务框架中:

    img

    可以发现,其实跟Seata的事务框架图长得非常的像,而区别呢就是我们的RM负责管理的就是我们的一阶段的try执行和二阶段的confirm/cancel,一样是由TM进行事务的Begin(发起),RM被TM调用后执行一阶段的Try方法,等待调用链路走完的时候,TM向TC告知二阶段决议,此时TC对RM驱动二阶段执行(下发通知,RM执行confirm/cancel).

    1.2.1 XA事务模式

    img

    如图所示,XA模式其实就是Seata底层利用了XA接口,在一阶段二阶段时自动处理.如一阶段时,XA的RM通过代理用户数据源,创建XAConnection,进行开启XA事务和XAprepare(此时XA的任何操作都会被持久化,即便宕机也能恢复),在二阶段时,TC通知RM进行XA分支的Commit/Rollback操作.

    AT模式是什么?

    首先我们来看一个例子:

    一阶段: 业务sql:update product set name = ‘GTS’ where name = ‘TXC’;

    可以看到一阶段的时候对用户是无感知的,业务sql是什么,还是什么.此时我们来简单说下AT这个时候会做那些事?

    解析sql并查询得到前镜像: select id, name, since from product where name = ‘TXC’;

    执行业务sql后,再查询执行后的数据作为后镜像: select id, name, since from product where id = 1;

    二阶段:

    提交: 仅需把事务相关信息删除即可.(理论上不删除也没问题)

    回滚: 取出前镜像进行回滚

    通过上述简单的例子,其实可以发现,AT模式就是自动补偿式事务,那AT具体都做了哪些呢?我们接下来看.

    AT如何保证分布式事务一致性?

    我们来看这个图:

    在这里插入图片描述

    可能刚看到会有疑问对吧?其实这个就是无侵入式,AT模式的做法示意图,首先用户还是从接口进入,到达了事务发起方,此时对业务开发者来说,这个发起方入口其实就是一个业务接口罢了,一样的执行业务sql,一样的return响应信息给客户端并没有什么改变.而背后就是用户的sql被Seata代理所托管,Seata-AT模式能感知到用户的所有sql,并对之进行操作,来保证一致性.

    但是Seata-AT是怎么做到无侵入的呢?我们接着看

    img

    首先我们可以看到如图所示,应用启动时,Seata会自动把用户的DataSource代理,还对JDBC操作熟悉的用户其实对DataSource还是比较熟悉的,拿到了DataSource,就等于掌握了数据源连接,也就能在背后做些"小动作",此时该对用户也是无感知无入侵.

    之后业务有请求进来,执行业务sql时,Seata会解析用户的sql,提取出表元数据,生成前镜像,再通过执行业务sql,保存执行sql后的后镜像(至于后镜像的用户之后会说到),再生成行锁,再注册分支是携带到Seata-Server 也就是TC端.

    此时在Client端的一阶段操作就已经完成了,无感知,无入侵.此时如果我们思考下,会发现这里其实有一个行锁,那么这个行锁是干嘛的呢?这就是要接着讲到Seata-AT是如何保证分布式下的事务隔离性,这里我们直接拿官网的示例来说.

    2.1写隔离

    • 一阶段本地事务提交前,需要确保先拿到 全局锁
    • 拿不到 全局锁 ,不能提交本地事务。
    • 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。

    以一个示例来说明:

    两个全局事务 tx1 和 tx2,分别对 a 表的 m 字段进行更新操作,m 的初始值 1000。

    tx1 先开始,开启本地事务,拿到本地锁,更新操作 m = 1000 - 100 = 900。本地事务提交前,先拿到该记录的 全局锁 ,本地提交释放本地锁。 tx2 后开始,开启本地事务,拿到本地锁,更新操作 m = 900 - 100 = 800。本地事务提交前,尝试拿该记录的 全局锁 ,tx1 全局提交前,该记录的全局锁被 tx1 持有,tx2 需要重试等待 全局锁

    img

    tx1 二阶段全局提交,释放 全局锁 。tx2 拿到 全局锁 提交本地事务。

    Write-Isolation: Rollback

    如果 tx1 的二阶段全局回滚,则 tx1 需要重新获取该数据的本地锁,进行反向补偿的更新操作,实现分支的回滚。

    此时,如果 tx2 仍在等待该数据的 全局锁,同时持有本地锁,则 tx1 的分支回滚会失败。分支的回滚会一直重试,直到 tx2 的 全局锁 等锁超时,放弃 全局锁 并回滚本地事务释放本地锁,tx1 的分支回滚最终成功。

    因为整个过程 全局锁 在 tx1 结束前一直是被 tx1 持有的,所以不会发生 脏写 的问题。

    这个时候隔离性相比大家已经比较明白了,此时一阶段的大部分操作相信大家也比较明白了,此时我们应该继续往下一阶段继续解析.

    2.2 AT 模式二阶段处理

    在这里插入图片描述

    我们由上图可见在二阶段提交时,其实TC仅是下发一个把之前一阶段做记录的undoLog删除,并把相关事务信息,如行锁删除,让之后因为在竞争锁被阻塞的事务顺利进行.

    而二阶段是回滚时,则要多做一些处理.

    首先在Client端收到TC告知的二阶段是回滚时,会去查到对应的事务的undolog,取出后镜像,对比当前数据的数据(因为SeataAT是从业务应用层面进行保护分布式事务,如果此时在数据库层面直接修改了库内信息,这个时候SeataAT的行锁是不起到隔离性),如果出现了在全局事务以外的数据修改,此时判定为脏写,而Seata因为无法感知这个脏写如何发生,此时只能打印日志和触发异常通知,告知用户需要人工介入(规范修改数据入口可避免脏写).

    而如果没有发生脏写就比较简单了,拿出前镜像,因为我们都知道事务是需要有原子性了,要么一起发生,要么都不发生,此时前镜像记录了发生之前的数据,进行回滚后,就达到了类似本地事务那样的原子性效果.回滚后,再把事务相关信息,如undolog,行锁进行删除.二阶段回滚算是告一段落了.

    既然介绍完了AT模式的一阶段及二阶段的原理思想方式,那么AT在Seata的分布式事务框架下是怎么样的呢?

    img

    我们可以看到,AT与其它事务模式在Seata事务框架中,会多出一个undolog的依赖(相对其它模式的入侵点),但是除此之外,对业务来说,几乎是零入侵性,这也就是为什么AT模式在Seata中受众广泛.

    2.3 AT 模式与Seata支持的其它二阶段模式区别

    首先我们应该明白,目前为止,不存在有任何一种分布式事务的可以满足所有场景.

    无论 AT 模式、TCC 模式还是 Saga 模式,这些模式的提出,本质上都源自 XA 规范对某些场景需求的无法满足.

    我们分为3点来做出对比:

    • 数据锁定

    AT 模式使用 全局锁 保障基本的 写隔离,实际上也是锁定数据的,只不过锁在 TC 侧集中管理,解锁效率高且没有阻塞的问题.

    TCC模式 无锁,利用本地事务排他锁特性,可预留资源,在全局事务决议后执行相应操作.

    XA 模式 在整个事务处理过程结束前,涉及数据都被锁定,读写都按隔离级别的定义约束起来.

    • 死锁(协议阻塞)

    XA 模式 prepare 后(老版本的数据库中,需要XA END后,再下发prepare(三阶段由来)),分支事务进入阻塞阶段,收到 XA commit 或 XA rollback 前必须阻塞等待。

    AT 可支持降级,因为锁存储再TC侧,如果Seata 出现bug或者其它问题,可直接降级,对后续业务调用链无任何影响.

    TCC 无此问题.

    • 性能

    性能的损耗主要来自两个方面: 一方面,事务相关处理和协调过程,增加单个事务的 RT;另一方面,并发事务数据的锁冲突,降低吞吐.其实主要原因就是上面的协议阻塞跟数据锁定造成.

    XA 模式它的一阶段不提交,在大并发场景由于锁存储再多个资源方(数据库等),加剧了性能耗损

    AT 模式 锁粒度细至行级(需要主键),且所有事务锁存储再TC侧,解锁高效迅速.

    TCC 模式 性能最优,仅需些许RPC开销,及2次本地事务的性能开销,但是需要符合资源预留场景,且是对业务侵入性较大(需要业务开发者每个接口分为3个,一个try,2个二阶段使用的confirm和cancel).

    可能很多同学对XA和AT的锁&协议阻塞不是特别理解,那么我们直接来看下图

    可以试着猜一下是哪个是XA?其实下图的是XA,因为它带来的锁粒度更大,且锁定时间更久,导致了并发性能相对AT事务模型来说,差的比较多,所以至今,XA模式的普及度都不很太高.

    Seata近期规划

    • 控制台

    首先控制台是我们Seata用户暴露已久的一个问题,没有一个可视化界面,使得用户对Seata的可靠性出现了怀疑,更由于没有控制台也局限了很多在Seata上可人工介入分布式事务的可能性等问题,所以未来在1.5.0的版本我们会带来控制台的加入,也欢迎更多的同学加入进来一起共建!

    • Raft集成

    Raft集成的原因,可能大部分用户不是特别知晓,首先我们要知道目前TC端的事务信息都是存储再外部存储器,比如数据库,redis,mongodb(PR阶段),这就造成了如果外部存储宕机,会造成Seata-Server集群的完全不可用,即便Server是集群部署,有10个甚至更多节点,都会因此而不可用.这是不可接受的.

    所以引入Raft来让每个Seata-Server的事务信息达到一致,即便某个节点宕机,也不会破坏事务信息准确性,从而也让分布式事务的一致性得到了更好的保证.(关于Seata-Server raft的实现之后会以新篇章来分享)

    • undoLog压缩

    这个是我们1.5.0 AT模式比较大的性能优化,由于一阶段操作的数据多且大,因为Seata在背后为用户插入了undolog信息,由此可能也会变得大,有造成了入库缓慢的可能,所以我们要把undolog进行压缩,使undolog的插入不再成为AT事务在分支数据量大的时候成为一个大的心梗开销.

    以下是我们Seata的交流群欢迎大家加入

    钉钉: 32033786

    QQ: 216012363

    总结

    AT 说到底就是实现对资源操作的代理,并记录原先&变更后的状态,并用锁保证该数据的隔离性.在调用链中出现异常时,还原所有分支数据,达到分布式事务下的’原子性’

    未来呢? redis,mongodb,mq? 尽情期待.

    Seata项目的最核心的价值在于:

    构建一个全面解决分布式事务问题的 标准化 平台。

    基于 Seata,上层应用架构可以根据实际场景的需求,灵活选择合适的分布式事务解决方案,非常欢迎大家参与到项目的建设中,共同打造一个标准化的分布式事务平台。

    img
    展开全文
  • 1. 从数据一致性谈起  一致性问题,“万恶之源”是数据冗余和分布并通过网络交互+网络异常是常态。 1.1 数据一致性的情形 主库、从库和缓存数据一致性,相同数据冗余,关系数据库,为保证关据库的高可用和高性能...
  • 分布式事务一致性的解决办法

    千次阅读 2022-03-30 20:22:59
    一致性事务 1.2pc 第一阶段:准备阶段,协调者会给各参与者发送准备命令,除了提交数据库事务以外的所有工作,都要在准备阶段完成 第二阶段:提交阶段,同步等待所有资源的响应之后就进入第二阶段即提交阶段...
  • Seata-AT如何保证分布式事务一致性.pptx
  • #资源达人分享计划#
  • 脂肪FAT,基于springboot,使用zookeeper,redis,spring异步,spring transactionManager的强一致性分布式事务解决方案框架介绍纯编码方式,强一致性。使用redis / zookeeper作为注册中心,代理事务的执行,使用...
  • 分布式事务数据一致性解决方案

    千次阅读 2020-09-03 01:01:53
    2PC 两阶段提交 由一个事务协调器器去通知各事务执行者准备事务、提交或回滚事务,它解决了数据一致性问题,但是通信时间、资源锁定时间太长,系统的可用性受到影响 利用RocketMq的消息事务机制,将生产者本地...
  • 服务发现工具的主要目标是用来服务查找和相互对话,为此该工具需要知道每个服务,这不是一个新概念,在Docker之前就已经存在很多类似的工具了,然而,容器带给了这些工具一个全新水平的需求。
  • 一阶段提交不需要“协调者”角色,各结点之间不存在协调操作,因此其事务执行时间比两阶段提交要短,但是提交的“危险期”是每一个事务的实际提交时间,相比于两阶段提交,一阶段提交出现在“不一致”的概率就变大了...
  • Camunda 补偿事件、事务子流程、分布式事务一致性补偿事件 Compensation Event事务子流程事务子流程如果没有暂停点事务子流程中补偿事件子流程不会触发Camunda 如何保证分布式事务一致性错误事件+补偿事件 就可以...
  • 分布式事务通过引入协调者的角色,对各个子系统状态进行统一。 2pc和3pc是基于数据库事务的分布式事务方案,提交和会滚建立在事务上,没有业务的入侵,但是资源锁定会影响业务执行效率。 tcc是基于业务的分布式事务...
  • LCN分布式事务框架框架介绍LCN分布式事务框架其本身并不创建事务,而是基于对本地事务的协调从而达到事务一致性的效果。核心步骤创建事务组是指在事务发起方开始执行业务代码之前先调用TxManager创建事务组对象,...
  • 除此以外还介绍了一些分布式事务相关的技术,如幂等性、全局一致性ID、分布式对象等。... 6-1 分布式事务介绍 6-2 spring分布式事务实现_使用JTA 6-3 spring分布式事务实现_不使用JTA 6-4 实例1-DB-DB 6-5 实例1-DB-...
  • 上篇文章:分布式系统漫谈【玖】_分布式事务一致性:协议支持 其实对于生产环境的分布式事务一致,各大互联网公司都是自己实现的解决方案,总结起来无非是异步、补偿、实时查询、定期校对几种模式,大部分场景都...
  • 一致性这个词重载的很厉害,在不同的语境和上下文中,它其实代表着不同的东西: 在事务的上下文中,比如ACID里的C,指的就是通常的一致性(Consistency) ...总结:这里事务一致性和强一致性算法根本不是一个东..
  • 分布式系统中,我们时常会遇到分布式事务的问题,如更新订单然后发送短信提醒,但是这两个操作需要操作不同的数据库,那么此时数据库的事务就不能处理好了 传统方式存在的问题: 1、先发送消息,再执行数据库事务,...
  • 分布式系统事务一致性解决方案大对比分布式系统事务一致性解决方案大对比
  • 分布式事务 基于消息补偿的最终一致性方案
  • 文章目录什么是事务事务(ACID)的特性对事务一致性的理解分布式一致性CAPBASE分布式事务本地事务柔性事务和刚性事务分布式一致性和分布式事务的理解一致性协议向量时钟NWR协议ZAB协议Gossip两阶段提交协议 (2PC)...
  • 对于分布式事务一般采用的都是最终一致性方案,而不是强一致性。而在使用最终一致性的方案时,一定要提到的一个概念是状态机。 什么是状态机?是一种特殊的组织代码的方式,用这种方式能够确保你的对象随时都知道...
  • 2.A和B微服务,如果A成功,B失败,此时通过RocketMQ重试,xxl-job等方式进行让B最终也成功,此时满足事务的最终一致性. RocketMQ的半消息,消息回查,重试机制,以及xxl-job捞失败的核心参数走相应逻辑,
  •  1)支付宝在扣款事务提交之前,向实时消息服务请求发送消息,实时消息服务只记录消息数据,而不真正发送,只有消息发送成功后才会提交事务;  2)当支付宝扣款事务被提交成功后,向实时消息服务确认发送。只有在...
  • java分布式-一致性

    千次阅读 2022-01-18 18:41:12
    java分布式-一致性
  • 分布式事务一致性

    千次阅读 2018-07-25 20:27:44
    今天在看书的时候,看到了分布式事务一致性问题,就赶紧记下来。 一、分布式事务介绍 在我们平时写的代码中,我们可以用一个事务包含许多个SQL调用,如果某一个数据库操作发生异常,就可以将之前的SQL操纵全部...
  • 使用MQ来保证分布式事务的最终一致性 使用MQ来保证分布式事务的最终一致性 参考URL:https://www.bbsmax.com/A/obzbM9QVdE/ 生产者的逻辑 1、订单入库 2、消息记录入库 3、发送消息(采用确认模式) 4、mq收到消息...
  • 上篇文章:分布式系统漫谈【拾】_分布式事务一致性:阿里方案 本文说说分布式事务的经典场景:秒杀的实现。 可以说秒杀是任何一个电商系统都无法避免的一个场景了,而在互联网公司面试过程中,也经常喜欢以这...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 167,936
精华内容 67,174
关键字:

分布式事务一致性