当前位置: 首页 > news >正文

深圳网站建设(信科网络)江西网站设计服务

深圳网站建设(信科网络),江西网站设计服务,哪些网站可以做国外生意,广州seo优化费用本文提纲如下#xff1a;0. 前言1. 单数据源事务 多数据源事务2. 常见分布式事务解决方案2.1. 分布式事务模型2.2. 二将军问题和幂等性2.3. 两阶段提交#xff08;2PC#xff09; 三阶段提交#xff08;3PC#xff09;方案2.4. TCC 方案2.5. 事务状态表方案2.… 本文提纲如下0. 前言1. 单数据源事务 多数据源事务2. 常见分布式事务解决方案2.1. 分布式事务模型2.2. 二将军问题和幂等性2.3. 两阶段提交2PC 三阶段提交3PC方案2.4. TCC 方案2.5. 事务状态表方案2.6. 基于消息中间件的最终一致性事务方案3. Seata in AT mode 的实现3.1. Seata in AT mode 工作流程概述3.2. Seata in AT mode 工作流程详述4. 结束语0. 前言 从 CPU 到内存、到磁盘、到操作系统、到网络计算机系统处处存在不可靠因素。工程师和科学家努力使用各种软硬件方法对抗这种不可靠因素保证数据和指令被正确地处理。在网络领域有 TCP 可靠传输协议、在存储领域有 Raid5 和 Raid6 算法、在数据库领域有基于 ARIES 算法理论实现的事务机制……这篇文章先介绍单机数据库事务的 ACID 特性然后指出分布式场景下操作多数据源面临的困境引出分布式系统中常用的分布式事务解决方案这些解决方案可以保证业务代码在操作多个数据源的时候能够像操作单个数据源一样具备 ACID 特性。文章在最后给出业界较为成熟的分布式事务框架——Seata 的 AT 模式全局事务的实现。1. 单数据源事务 多数据源事务 如果一个应用程序在一次业务流中通过连接驱动和数据源接口只连接并查询这里的查询是广义的包括增删查改等一个特定的数据库该应用程序就可以利用数据库提供的事务机制如果数据库支持事务的话保证对库中记录所进行的操作的可靠性这里的可靠性有四种语义- 原子性A- 一致性C- 隔离性I- 持久性D笔者在这里不再对这四种语义进行解释了解单数据源事务及其 ACID 特性是读者阅读这篇文章的前提。单个数据库实现自身的事务特性是一个复杂又微妙的过程例如 MySQL 的 InnoDB 引擎通过 Undo Log Redo Log ARIES 算法来实现。这是一个很宏大的话题不在本文的描述范围读者有兴趣的话可自行研究。单数据源事务也可以叫做单机事务或者本地事务。在分布式场景下一个系统由多个子系统构成每个子系统有独立的数据源。多个子系统之间通过互相调用来组合出更复杂的业务。在时下流行的微服务系统架构中每一个子系统被称作一个微服务同样每个微服务都维护自己的数据库以保持独立性。例如一个电商系统可能由购物微服务、库存微服务、订单微服务等组成。购物微服务通过调用库存微服务和订单微服务来整合出购物业务。用户请求购物微服务商完成下单时购物微服务一方面调用库存微服务扣减相应商品的库存数量另一方面调用订单微服务插入订单记录为了后文描述分布式事务解决方案的方便这里给出的是一个最简单的电商系统微服务划分和最简单的购物业务流程后续的支付、物流等业务不在考虑范围内。电商系统模型如下图所示在用户购物的业务场景中shopping-service 的业务涉及两个数据库库存库repo_db和订单库repo_db也就是 g 购物业务是调用多数据源来组合而成的。作为一个面向消费者的系统电商系统要保证购物业务的高度可靠性这里的可靠性同样有 ACID 四种语义。但是一个数据库的本地事务机制仅仅对落到自己身上的查询操作这里的查询是广义的包括增删改查等起作用无法干涉对其他数据库的查询操作。所以数据库自身提供的本地事务机制无法确保业务对多数据源全局操作的可靠性。基于此针对多数据源操作提出的分布式事务机制就出现了。分布式事务也可以叫做全局事务。2. 常见分布式事务解决方案 2.1. 分布式事务模型描述分布式事务常常会使用以下几个名词- 事务参与者例如每个数据库就是一个事务参与者- 事务协调者访问多个数据源的服务程序例如 shopping-service 就是事务协调者- 资源管理器Resource Manager, RM通常与事务参与者同义- 事务管理器Transaction Manager, TM通常与事务协调者同义在分布式事务模型中一个 TM 管理多个 RM即一个服务程序访问多个数据源TM 是一个全局事务管理器协调多方本地事务的进度使其共同提交或回滚最终达成一种全局的 ACID 特性。2.2. 二将军问题和幂等性二将军问题是网络领域的一个经典问题用于表达计算机网络中互联协议设计的微妙性和复杂性。这里给出一个二将军问题的简化版本一支白军被围困在一个山谷中山谷的左右两侧是蓝军。困在山谷中的白军人数多于山谷两侧的任意一支蓝军而少于两支蓝军的之和。若一支蓝军对白军单独发起进攻则必败无疑但若两支蓝军同时发起进攻则可取胜。两只蓝军的总指挥位于山谷左侧他希望两支蓝军同时发起进攻这样就要把命令传到山谷右侧的蓝军以告知发起进攻的具体时间。假设他们只能派遣士兵穿越白军所在的山谷唯一的通信信道来传递消息那么在穿越山谷时士兵有可能被俘虏。只有当送信士兵成功往返后总指挥才能确认这场战争的胜利上方图。现在问题来了派遣出去送信的士兵没有回来则左侧蓝军中的总指挥能不能决定按命令中约定的时间发起进攻答案是不确定派遣出去送信的士兵没有回来他可能遇到两种状况1命令还没送达就被俘虏了中间图这时候右侧蓝军根本不知道要何时进攻2命令送达但返回途中被俘虏了下方图这时候右侧蓝军知道要何时进攻但左侧蓝军不知道右侧蓝军是否知晓进攻时间。类似的问题在计算机网络中普遍存在例如发送者给接受者发送一个 HTTP 请求或者 MySQL 客户端向 MySQL 服务器发送一条插入语句然后超时了没有得到响应。请问服务器是写入成功了还是失败了答案是不确定有以下几种情况1可能请求由于网络故障根本没有送到服务器因此写入失败2可能服务器收到了也写入成功了但是向客户端发送响应前服务器宕机了3可能服务器收到了也写入成功了也向客户端发送了响应但是由于网络故障未送到客户端。无论哪种场景在客户端看来都是一样的结果它发出的请求没有得到响应。为了确保服务端成功写入数据客户端只能重发请求直至接收到服务端的响应。类似的问题问题被称为网络二将军问题。网络二将军问题的存在使得消息的发送者往往要重复发送消息直到收到接收者的确认才认为发送成功但这往往又会导致消息的重复发送。例如电商系统中订单模块调用支付模块扣款的时候如果网络故障导致二将军问题出现扣款请求重复发送产生的重复扣款结果显然是不能被接受的。因此要保证一次事务中的扣款请求无论被发送多少次接收方有且只执行一次扣款动作这种保证机制叫做接收方的幂等性。2.3. 两阶段提交2PC 三阶段提交3PC方案2PC 是一种实现分布式事务的简单模型这两个阶段是1准备阶段事务协调者向各个事务参与者发起询问请求“我要执行全局事务了这个事务涉及到的资源分布在你们这些数据源中分别是……你们准备好各自的资源即各自执行本地事务到待提交阶段”。各个参与者协调者回复 yes表示已准备好允许提交全局事务或 no表示本参与者无法拿到全局事务所需的本地资源因为它被其他本地事务锁住了或超时。2提交阶段如果各个参与者回复的都是 yes则协调者向所有参与者发起事务提交操作然后所有参与者收到后各自执行本地事务提交操作并向协调者发送 ACK如果任何一个参与者回复 no 或者超时则协调者向所有参与者发起事务回滚操作然后所有参与者收到后各自执行本地事务回滚操作并向协调者发送 ACK。2PC 的流程如下图所示从上图可以看出要实现 2PC所有的参与者都要实现三个接口Prepare()TM 调用该接口询问各个本地事务是否就绪Commit()TM 调用该接口要求各个本地事务提交Rollback()TM 调用该接口要求各个本地事务回滚可以将这三个接口简单地但不严谨地理解成 XA 协议。XA 协议是 X/Open 提出的分布式事务处理标准。MySQL、Oracle、DB2 这些主流数据库都实现了 XA 协议因此都能被用于实现 2PC 事务模型。2PC 简明易懂但存在如下的问题1性能差在准备阶段要等待所有的参与者返回才能进入阶段二在这期间各个参与者上面的相关资源被排他地锁住参与者上面意图使用这些资源的本地事务只能等待。因为存在这种同步阻塞问题所以影响了各个参与者的本地事务并发度2准备阶段完成后如果协调者宕机所有的参与者都收不到提交或回滚指令导致所有参与者“不知所措”3在提交阶段协调者向所有的参与者发送了提交指令如果一个参与者未返回 ACK那么协调者不知道这个参与者内部发生了什么由于网络二将军问题的存在这个参与者可能根本没收到提交指令一直处于等待接收提交指令的状态也可能收到了并成功执行了本地提交但返回的 ACK 由于网络故障未送到协调者上也就无法决定下一步是否进行全体参与者的回滚。2PC 之后又出现了 3PC把两阶段过程变成了三阶段过程分别是询问阶段、准备阶段、提交或回滚阶段这里不再详述。3PC 利用超时机制解决了 2PC 的同步阻塞问题避免资源被永久锁定进一步加强了整个事务过程的可靠性。但是 3PC 同样无法应对类似的宕机问题只不过出现多数据源中数据不一致问题的概率更小。2PC 除了性能和可靠性上存在问题它的适用场景也很局限它要求参与者实现了 XA 协议例如使用实现了 XA 协议的数据库作为参与者可以完成 2PC 过程。但是在多个系统服务利用 api 接口相互调用的时候就不遵守 XA 协议了这时候 2PC 就不适用了。所以 2PC 在分布式应用场景中很少使用。所以前文提到的电商场景无法使用 2PC因为 shopping-service 通过 RPC 接口或者 Rest 接口调用 repo-service 和 order-service 间接访问 repo_db 和 order_db。除非 shopping-service 直接配置 repo_db 和 order_db 作为自己的数据库。2.4. TCC 方案描述 TCC 方案使用的电商微服务模型如下图所示在这个模型中shopping-service 是事务协调者repo-service 和 order-service 是事务参与者。上文提到2PC 要求参与者实现了 XA 协议通常用来解决多个数据库之间的事务问题比较局限。在多个系统服务利用 api 接口相互调用的时候就不遵守 XA 协议了这时候 2PC 就不适用了。现代企业多采用分布式的微服务因此更多的是要解决多个微服务之间的分布式事务问题。TCC 就是一种解决多个微服务之间的分布式事务问题的方案。TCC 是 Try、Confirm、Cancel 三个词的缩写其本质是一个应用层面上的 2PC同样分为两个阶段1阶段一准备阶段。协调者调用所有的每个微服务提供的 try 接口将整个全局事务涉及到的资源锁定住若锁定成功 try 接口向协调者返回 yes。2阶段二提交阶段。若所有的服务的 try 接口在阶段一都返回 yes则进入提交阶段协调者调用所有服务的 confirm 接口各个服务进行事务提交。如果有任何一个服务的 try 接口在阶段一返回 no 或者超时则协调者调用所有服务的 cancel 接口。TCC 的流程如下图所示这里有个关键问题既然 TCC 是一种服务层面上的 2PC它是如何解决 2PC 无法应对宕机问题的缺陷的呢答案是不断重试。由于 try 操作锁住了全局事务涉及的所有资源保证了业务操作的所有前置条件得到满足因此无论是 confirm 阶段失败还是 cancel 阶段失败都能通过不断重试直至 confirm 或 cancel 成功所谓成功就是所有的服务都对 confirm 或者 cancel 返回了 ACK。这里还有个关键问题在不断重试 confirm 和 cancel 的过程中考虑到网络二将军问题的存在有可能重复进行了 confirm 或 cancel因此还要再保证 confirm 和 cancel 操作具有幂等性也就是整个全局事务中每个参与者只进行一次 confirm 或者 cancel。实现 confirm 和 cancel 操作的幂等性有很多解决方案例如每个参与者可以维护一个去重表可以利用数据库表实现也可以使用内存型 KV 组件实现记录每个全局事务以全局事务标记 XID 区分是否进行过 confirm 或 cancel 操作若已经进行过则不再重复执行。TCC 由支付宝团队提出被广泛应用于金融系统中。我们用银行账户余额购买基金时会注意到银行账户中用于购买基金的那部分余额首先会被冻结由此我们可以猜想这个过程大概就是 TCC 的第一阶段。2.5. 事务状态表方案另外有一种类似 TCC 的事务解决方案借助事务状态表来实现。假设要在一个分布式事务中实现调用 repo-service 扣减库存、调用 order-service 生成订单两个过程。在这种方案中协调者 shopping-service 维护一张如下的事务状态表分布式事务 ID事务内容事务状态global_trx_id_1操作 1调用 repo-service 扣减库存操作 2调用 order-service 生成订单状态 1初始状态 2操作 1 成功状态 3操作 1、2 成功初始状态为 1每成功调用一个服务则更新一次状态最后所有的服务调用成功状态更新到 3。有了这张表就可以启动一个后台任务扫描这张表中事务的状态如果一个分布式事务一直设置一个事务周期阈值未到状态 3说明这条事务没有成功执行于是可以重新调用 repo-service 扣减库存、调用 order-service 生成订单。直至所有的调用成功事务状态到 3。如果多次重试仍未使得状态到 3可以将事务状态置为 error通过人工介入进行干预。由于存在服务的调用重试因此每个服务的接口要根据全局的分布式事务 ID 做幂等原理同 2.4 节的幂等性实现。2.6. 基于消息中间件的最终一致性事务方案无论是 2PC 3PC 还是 TCC、事务状态表基本都遵守 XA 协议的思想即这些方案本质上都是事务协调者协调各个事务参与者的本地事务的进度使所有本地事务共同提交或回滚最终达成一种全局的 ACID 特性。在协调的过程中协调者需要收集各个本地事务的当前状态并根据这些状态发出下一阶段的操作指令。但是这些全局事务方案由于操作繁琐、时间跨度大或者在全局事务期间会排他地锁住相关资源使得整个分布式系统的全局事务的并发度不会太高。这很难满足电商等高并发场景对事务吞吐量的要求因此互联网服务提供商探索出了很多与 XA 协议背道而驰的分布式事务解决方案。其中利用消息中间件实现的最终一致性全局事务就是一个经典方案。为了表现出这种方案的精髓我将使用如下的电商系统微服务结构来进行描述在这个模型中用户不再是请求整合后的 shopping-service 进行下单而是直接请求 order-service 下单order-service 一方面添加订单记录另一方面会调用 repo-service 扣减库存。这种基于消息中间件的最终一致性事务方案常常被误解成如下的实现方式这种实现方式的流程是1order-service 负责向 MQ server 发送扣减库存消息repo_deduction_msgrepo-service 订阅 MQ server 中的扣减库存消息负责消费消息。2用户下单后order-service 先执行插入订单记录的查询语句后将 repo_deduction_msg 发到消息中间件中这两个过程放在一个本地事务中进行一旦“执行插入订单记录的查询语句”失败导致事务回滚“将 repo_deduction_msg 发到消息中间件中”就不会发生同样一旦“将 repo_deduction_msg 发到消息中间件中”失败抛出异常也会导致“执行插入订单记录的查询语句”操作回滚最终什么也没有发生。3repo-service 接收到 repo_deduction_msg 之后先执行库存扣减查询语句后向 MQ sever 反馈消息消费完成 ACK这两个过程放在一个本地事务中进行一旦“执行库存扣减查询语句”失败导致事务回滚“向 MQ sever 反馈消息消费完成 ACK”就不会发生MQ server 在 Confirm 机制的驱动下会继续向 repo-service 推送该消息直到整个事务成功提交同样一旦“向 MQ sever 反馈消息消费完成 ACK”失败抛出异常也对导致“执行库存扣减查询语句”操作回滚MQ server 在 Confirm 机制的驱动下会继续向 repo-service 推送该消息直到整个事务成功提交。这种做法看似很可靠。但没有考虑到网络二将军问题的存在有如下的缺陷1存在网络的 2 将军问题上面第 2步中 order-service 发送 repo_deduction_msg 消息失败对于发送方 order-service 来说可能是消息中间件没有收到消息也可能是中间件收到了消息但向发送方 order-service 响应的 ACK 由于网络故障没有被 order-service 收到。因此 order-service 贸然进行事务回滚撤销“执行插入订单记录的查询语句”是不对的因为 repo-service 那边可能已经接收到 repo_deduction_msg 并成功进行了库存扣减这样 order-service 和 repo-service 两方就产生了数据不一致问题。2repo-service 和 order-service 把网络调用与 MQ server 通信放在本地数据库事务里可能会因为网络延迟产生数据库长事务影响数据库本地事务的并发度。015以上是被误解的实现方式下面给出正确的实现方式如下所示上图所示的方案利用消息中间件如 rabbitMQ 来实现分布式下单及库存扣减过程的最终一致性。对这幅图做以下说明1order-service 中 在 t_order 表添加订单记录 在 t_local_msg 添加对应的扣减库存消息这两个过程要在一个事务中完成保证过程的原子性。同样repo-service 中 检查本次扣库存操作是否已经执行过 执行扣减库存如果本次扣减操作没有执行过 写判重表 向 MQ sever 反馈消息消费完成 ACK这四个过程也要在一个事务中完成保证过程的原子性。2order-service 中有一个后台程序源源不断地把消息表中的消息传送给消息中间件成功后则删除消息表中对应的消息。如果失败了也会不断尝试重传。由于存在网络 2 将军问题即当 order-service 发送给消息中间件的消息网络超时时这时候消息中间件可能收到了消息但响应 ACK 失败也可能没收到order-service 会再次发送该消息直至消息中间件响应 ACK 成功这样可能发生消息的重复发送不过没关系只要保证消息不丢失不乱序就行后面 repo-service 会做去重处理。3消息中间件向 repo-service 推送 repo_deduction_msgrepo-service 成功处理完成后会向中间件响应 ACK消息中间件收到这个 ACK 才认为 repo-service 成功处理了这条消息否则会重复推送该消息。但是有这样的情形repo-service 成功处理了消息向中间件发送的 ACK 在网络传输中由于网络故障丢失了导致中间件没有收到 ACK 重新推送了该消息。这也要靠 repo-service 的消息去重特性来避免消息重复消费。4在 2和 3中提到了两种导致 repo-service 重复收到消息的原因一是生产者重复生产二是中间件重传。为了实现业务的幂等性repo-service 中维护了一张判重表这张表中记录了被成功处理的消息的 id。repo-service 每次接收到新的消息都先判断消息是否被成功处理过若是的话不再重复处理。通过这种设计实现了消息在发送方不丢失消息在接收方不被重复消费联合起来就是消息不漏不重严格实现了 order-service 和 repo-service 的两个数据库中数据的最终一致性。基于消息中间件的最终一致性全局事务方案是互联网公司在高并发场景中探索出的一种创新型应用模式利用 MQ 实现微服务之间的异步调用、解耦合和流量削峰支持全局事务的高并发并保证分布式数据记录的最终一致性。3. Seata in AT mode 的实现 第 2 章给出了实现实现分布式事务的集中常见的理论模型。本章给出业界开源分布式事务框架 Seata 的实现。Seata 为用户提供了 AT、TCC、SAGA 和 XA 事务模式。其中 AT 模式是 Seata 主推的事务模式因此本章分析 Seata in AT mode 的实现。使用 AT 有一个前提那就是微服务使用的数据库必须是支持事务的关系型数据库。3.1. Seata in AT mode 工作流程概述Seata 的 AT 模式建立在关系型数据库的本地事务特性的基础之上通过数据源代理类拦截并解析数据库执行的 SQL记录自定义的回滚日志如需回滚则重放这些自定义的回滚日志即可。AT 模式虽然是根据 XA 事务模型2PC演进而来的但是 AT 打破了 XA 协议的阻塞性制约在一致性和性能上取得了平衡。AT 模式是基于 XA 事务模型演进而来的它的整体机制也是一个改进版本的两阶段提交协议。AT 模式的两个基本阶段是1第一阶段首先获取本地锁执行本地事务业务数据操作和记录回滚日志在同一个本地事务中提交最后释放本地锁2第二阶段如需全局提交异步删除回滚日志即可这个过程很快就能完成。如需要回滚则通过第一阶段的回滚日志进行反向补偿。本章描述 Seata in AT mode 的工作原理使用的电商微服务模型如下图所示在上图中协调者 shopping-service 先调用参与者 repo-service 扣减库存后调用参与者 order-service 生成订单。这个业务流使用 Seata in XA mode 后的全局事务流程如下图所示上图描述的全局事务执行流程为1shopping-service 向 Seata 注册全局事务并产生一个全局事务标识 XID2将 repo-service.repo_db、order-service.order_db 的本地事务执行到待提交阶段事务内容包含对 repo-service.repo_db、order-service.order_db 进行的查询操作以及写每个库的 undo_log 记录3repo-service.repo_db、order-service.order_db 向 Seata 注册分支事务并将其纳入该 XID 对应的全局事务范围4提交 repo-service.repo_db、order-service.order_db 的本地事务5repo-service.repo_db、order-service.order_db 向 Seata 汇报分支事务的提交状态6Seata 汇总所有的 DB 的分支事务的提交状态决定全局事务是该提交还是回滚7Seata 通知 repo-service.repo_db、order-service.order_db 提交/回滚本地事务若需要回滚采取的是补偿式方法其中 12345属于第一阶段67属于第二阶段。3.2. Seata in AT mode 工作流程详述在上面的电商业务场景中购物服务调用库存服务扣减库存调用订单服务创建订单显然这两个调用过程要放在一个事务里面。即 start global_trxcall 库存服务的扣减库存接口call 订单服务的创建订单接口commit global_trx在库存服务的数据库中存在如下的库存表 t_repoidproduction_codenamecountprice1000120001xx 键盘98200.01000220002yy 鼠标199100.0在订单服务的数据库中存在如下的订单表 t_orderidorder_codeuser_idproduction_codecountprice30001202010250000140001200021100.030002202010250000140001200012400.0现在id 为 40002 的用户要购买一只商品代码为 20002 的鼠标整个分布式事务的内容为1在库存服务的库存表中将记录idproduction_codenamecountprice1000220002yy 鼠标199100.0修改为idproduction_codenamecountprice1000220002yy 鼠标198100.02在订单服务的订单表中添加一条记录idorder_codeuser_idproduction_codecountprice30003202010250000240002200021100.0以上操作在 AT 模式的第一阶段的流程图如下从 AT 模式第一阶段的流程来看分支的本地事务在第一阶段提交完成之后就会释放掉本地事务锁定的本地记录。这是 AT 模式和 XA 最大的不同点在 XA 事务的两阶段提交中被锁定的记录直到第二阶段结束才会被释放。所以 AT 模式减少了锁记录的时间从而提高了分布式事务的处理效率。AT 模式之所以能够实现第一阶段完成就释放被锁定的记录是因为 Seata 在每个服务的数据库中维护了一张 undo_log 表其中记录了对 t_order / t_repo 进行操作前后记录的镜像数据即便第二阶段发生异常只需回放每个服务的 undo_log 中的相应记录即可实现全局回滚。undo_log 的表结构idbranch_idxidcontextrollback_infolog_statuslog_createdlog_modified……分支事务 ID全局事务 ID……分支事务操作的记录在事务前后的记录镜像即 beforeImage 和 afterImage………………第一阶段结束之后Seata 会接收到所有分支事务的提交状态然后决定是提交全局事务还是回滚全局事务。1若所有分支事务本地提交均成功则 Seata 决定全局提交。Seata 将分支提交的消息发送给各个分支事务各个分支事务收到分支提交消息后会将消息放入一个缓冲队列然后直接向 Seata 返回提交成功。之后每个本地事务会慢慢处理分支提交消息处理的方式为删除相应分支事务的 undo_log 记录。之所以只需删除分支事务的 undo_log 记录而不需要再做其他提交操作是因为提交操作已经在第一阶段完成了这也是 AT 和 XA 不同的地方。这个过程如下图所示分支事务之所以能够直接返回成功给 Seata是因为真正关键的提交操作在第一阶段已经完成了清除 undo_log 日志只是收尾工作即便清除失败了也对整个分布式事务不产生实质影响。2若任一分支事务本地提交失败则 Seata 决定全局回滚将分支事务回滚消息发送给各个分支事务由于在第一阶段各个服务的数据库上记录了 undo_log 记录分支事务回滚操作只需根据 undo_log 记录进行补偿即可。全局事务的回滚流程如下图所示这里对图中的 2、3 步做进一步的说明1由于上文给出了 undo_log 的表结构所以可以通过 xid 和 branch_id 来找到当前分支事务的所有 undo_log 记录2拿到当前分支事务的 undo_log 记录之后首先要做数据校验如果 afterImage 中的记录与当前的表记录不一致说明从第一阶段完成到此刻期间有别的事务修改了这些记录这会导致分支事务无法回滚向 Seata 反馈回滚失败如果 afterImage 中的记录与当前的表记录一致说明从第一阶段完成到此刻期间没有别的事务修改这些记录分支事务可回滚进而根据 beforeImage 和 afterImage 计算出补偿 SQL执行补偿 SQL 进行回滚然后删除相应 undo_log向 Seata 反馈回滚成功。事务具有 ACID 特性全局事务解决方案也在尽量实现这四个特性。以上关于 Seata in AT mode 的描述很显然体现出了 AT 的原子性、一致性和持久性。下面着重描述一下 AT 如何保证多个全局事务的隔离性的。在 AT 中当多个全局事务操作同一张表时通过全局锁来保证事务的隔离性。下面描述一下全局锁在读隔离和写隔离两个场景中的作用原理1写隔离若有全局事务在改/写/删记录另一个全局事务对同一记录进行的改/写/删要被隔离起来即写写互斥写隔离是为了在多个全局事务对同一张表的同一个字段进行更新操作时避免一个全局事务在没有被提交成功之前所涉及的数据被其他全局事务修改。写隔离的基本原理是在第一阶段本地事务开启本地事务的时候本地事务会对涉及到的记录加本地锁提交之前确保拿到全局锁。如果拿不到全局锁就不能提交本地事务并且不断尝试获取全局锁直至超出重试次数放弃获取全局锁回滚本地事务释放本地事务对记录加的本地锁。假设有两个全局事务 gtrx_1 和 gtrx_2 在并发操作库存服务意图扣减如下记录的库存数量idproduction_codenamecountprice1000220002yy 鼠标198100.0AT 实现写隔离过程的时序图如下图中1、2、3、4 属于第一阶段5 属于第二阶段。在上图中 gtrx_1 和 gtrx_2 均成功提交如果 gtrx_1 在第二阶段执行回滚操作那么 gtrx_1 需要重新发起本地事务获取本地锁然后根据 undo_log 对这个 id10002 的记录进行补偿式回滚。此时 gtrx_2 仍在等待全局锁且持有这个 id10002 的记录的本地锁因此 gtrx_1 会回滚失败gtrx_1 回滚需要同时持有全局锁和对 id10002 的记录加的本地锁回滚失败的 gtrx_1 会一直重试回滚。直到旁边的 gtrx_2 获取全局锁的尝试次数超过阈值gtrx_2 会放弃获取全局锁发起本地回滚本地回滚结束后自然会释放掉对这个 id10002 的记录加的本地锁。此时gtrx_1 终于可以成功对这个 id10002 的记录加上了本地锁同时拿到了本地锁和全局锁的 gtrx_1 就可以成功回滚了。整个过程全局锁始终在 gtrx_1 手中并不会发生脏写的问题。整个过程的流程图如下所示2读隔离若有全局事务在改/写/删记录另一个全局事务对同一记录的读取要被隔离起来即读写互斥在数据库本地事务的隔离级别为读已提交、可重复读、串行化时读未提交不起什么隔离作用一般不使用Seata AT 全局事务模型产生的隔离级别是读未提交也就是说一个全局事务会看到另一个全局事务未全局提交的数据产生脏读从前文的第一阶段和第二阶段的流程图中也可以看出这一点。这在最终一致性的分布式事务模型中是可以接受的。如果要求 AT 模型一定要实现读已提交的事务隔离级别可以利用 Seata 的 SelectForUpdateExecutor 执行器对 SELECT FOR UPDATE 语句进行代理。SELECT FOR UPDATE 语句在执行时会申请全局锁如果全局锁已经被其他全局事务占有则回滚 SELECT FOR UPDATE 语句的执行释放本地锁并且重试 SELECT FOR UPDATE 语句。在这个过程中查询请求会被阻塞直到拿到全局锁也就是要读取的记录被其他全局事务提交读到已被全局事务提交的数据才返回。这个过程如下图所示4. 结束语 XA 协议是 X/Open 提出的分布式事务处理标准。文中提到的 2PC、3PC、TCC、本地事务表、Seata in AT mode无论哪一种本质都是事务协调者协调各个事务参与者的本地事务的进度使使所有本地事务共同提交或回滚最终达成一种全局的 ACID 特性。在协调的过程中协调者需要收集各个本地事务的当前状态并根据这些状态发出下一阶段的操作指令。这个思想就是 XA 协议的要义我们可以说这些事务模型遵守或大致遵守了 XA 协议。基于消息中间件的最终一致性事务方案是互联网公司在高并发场景中探索出的一种创新型应用模式利用 MQ 实现微服务之间的异步调用、解耦合和流量削峰保证分布式数据记录的最终一致性。它显然不遵守 XA 协议。对于某项技术可能存在业界标准或协议但实践者针对具体应用场景的需求或者出于简便的考虑给出与标准不完全相符的实现甚至完全不相符的实现这在工程领域是一种常见的现象。TCC 方案如此、基于消息中间件的最终一致性事务方案如此、Seata in AT mode 模式也如此。而新的标准往往就在这些创新中产生。你难道真的没有发现 2.6 节基于消息中间件的最终一致性事务方案给出的正确方案中存在的业务漏洞吗请各位重新看下这张图仔细品一品两个微服务的调用方向把你的想法留在评论区吧 :-) 往期推荐 23张图万字详解「链表」从小白到大佬嗯查询滑动窗口最大值的这4种方法不错....队列实现栈的3种方法全都击败了100%的用户关注我每天陪你进步一点点
http://www.huolong8.cn/news/297011/

相关文章:

  • 怎么网站是什么语言做的app外包网站
  • 六安网站建设 220百度seo优化技术
  • 外包网seo文章推广
  • vs2017做的网站如何发布yandx引擎入口
  • 徐州做网站的公司有几家设计网页推荐
  • 中国视觉设计网站网站推广方法渠道
  • 重庆建设技术发展中心网站如何看待百度竞价排名
  • 品牌网站建设權威大蝌蚪石家庄软件外包
  • 淄博做网站建设公司建个人网站有什么好处
  • 单页面网站 万网x3优设设计师网站
  • 设计一个网站多少钱网站建设哪家专业
  • 网站登录失败怎么回事外贸网站如何做推广电话
  • 轻量级网站开发移动营销
  • 剑网三魁首怎么做网站深圳软件公司排行
  • 如何识别网站建设小程序推广运营公司
  • 网站建设需要在哪备案微信知彼网络网站建设
  • 快速微信网站设计用织梦软件如何做网站
  • 太原制作网站的工作室wordpress三合一主题
  • 石景山网站seo优化排名网站用什么语言开发
  • 怎么做自己网站的后台小红书推广有用吗
  • 网站上传教程网站页面做
  • 企业网站推广总结网店推广方案范文
  • 漳州市城乡住房建设局网站网络营销是一种什么营销
  • 网站建设全程揭秘 光盘文件一个好的网站需要具备什么
  • 做响应式网站怎么设计软件外包公司的出路
  • 网站首页设计布局方式北京市住房城乡建设门户网站
  • 做返利网站能赚钱么厦门装修公司排名前十
  • 番禺网站建设服务百度免费网站申请注册
  • 云网站建设017年青深圳网站建设制作营销
  • 网站开发 一个页面多少钱西宁高端网站开发公司