微服务分布式事务介绍

编程入门 行业动态 更新时间:2024-10-12 18:23:02

微服务<a href=https://www.elefans.com/category/jswz/34/1770120.html style=分布式事务介绍"/>

微服务分布式事务介绍

参考文章:

Seata 是什么

微服务中分布式事务的解决方案-SpringCloudAlibaba No.5_Fire king的博客-CSDN博客_微服务事务解决方案


TXC分布式事务简介_浮生忆梦的博客-CSDN博客_txc是什么意思

微服务架构下分布式事务解决方案 —— 阿里GTS-蒲公英云

SpringCloud Alibaba微服务实战七 - 分布式事务_AlbenXie的博客-CSDN博客_springcloudalibaba 分布式事务

Seata源码解析8——GlobalTransactional注解_野生的程序员的博客-CSDN博客_globaltransactional

Spring Cloud Alibaba | 微服务分布式事务之Seata-博客

分布式事务处理【TX-LCN】_脑袋不灵光的小白羊的博客-CSDN博客_tx-lcn

Spring Cloud Alibaba —— 分布式事务组件_桃花键神的博客-CSDN博客


亿级流量架构之分布式事务解决方案对比 - JavaShuo

SpringCloud Alibaba微服务实战七 - 分布式事务_AlbenXie的博客-CSDN博客_springcloudalibaba 分布式事务

关于分布式事务BASE模型和柔性事务TCC_发呆程序员的博客-CSDN博客_base柔性事务

分布式事务相关概念

分布式事务主要涉及以下概念:

  1. 事务:由一组操作构成的可靠、独立的工作单元,事务具备 ACID 的特性,即原子性、一致性、隔离性和持久性。
  2. 本地事务:本地事务由本地资源管理器(通常指数据库管理系统 DBMS,例如 MySQL、Oracle 等)管理,严格地支持 ACID 特性,高效可靠。本地事务不具备分布式事务的处理能力,隔离的最小单位受限于资源管理器,即本地事务只能对自己数据库的操作进行控制,对于其他数据库的操作则无能为力。
  3. 全局事务:全局事务指的是一次性操作多个资源管理器完成的事务,由一组分支事务组成。
  4. 分支事务:在分布式事务中,就是一个个受全局事务管辖和协调的本地事务。

我们可以将分布式事务理解成一个包含了若干个分支事务的全局事务。全局事务的职责是协调其管辖的各个分支事务达成一致,要么一起成功提交,要么一起失败回滚。此外,通常分支事务本身就是一个满足 ACID 特性的本地事务。
 

三种常用的分布式事务解决方案 

1. XA分布式事务协议 - 2PC(两阶段提交实现)

这里的PC实际上指的是Prepare和Commit,也就是说它分为两个阶段,一个是准备一个是提交,整个过程的参与者一共有两个角色,一个是事务的执行者,一个是事务的协调者,实际上整个分布式事务的运作都需要依靠协调者来维持:

在准备和提交阶段,会进行:

  • 准备阶段:
  1. 分布式事务是由协调者来开启,首先协调者会向所有的事务执行者发送事务内容,等待所有的事务执行者答复。
  2. 各个事务执行者开始执行事务操作,但是不进行提交,并将undo和redo信息记录到事务日志中。
  3. 如果事务执行者执行事务成功,那么就告诉协调者成功Yes,否则告诉协调者失败No,不能提交事务。

  •  提交阶段:

当所有的执行者都反馈完成之后,进入第二阶段。

  1. 协调者会检查各个执行者的反馈内容,如果所有的执行者都返回成功,那么就告诉所有的执行者可以提交事务了,最后再释放锁资源。
  2. 如果有至少一个执行者返回失败或是超时,那么就让所有的执行者都回滚,分布式事务执行失败。

虽然这种方式看起来比较简单,但是存在以下几个问题:

  • 事务协调者是非常核心的角色,一旦出现问题,将导致整个分布式事务不能正常运行。
  • 如果提交阶段发生网络问题,导致某些事务执行者没有收到协调者发来的提交命令,将导致某些执行者提交某些执行者没提交,这样肯定是不行的。

两阶段提交理论的一个广泛工业应用是XA协议。目前几乎所有收费的商业数据库都支持XA协议。XA协议已在业界成熟运行数十年,但目前它在互联网海量流量的应用场景中,吞吐量这个瓶颈变得十分致命,因此很少被用到。 

2. XA分布式事务协议 - 3PC(三阶段提交实现)

三阶段提交是在二阶段提交基础上的改进版本,主要是加入了超时机制,同时在协调者和执行者中都引入了超时机制。

三个阶段分别进行:

  • CanCommit阶段:
  1. ​​​​​​协调者向执行者发送CanCommit请求,询问是否可以执行事务提交操作,然后开始等待执行者的响应。
  2. 执行者接收到请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回Yes响应,并进入预备状态,否则返回No
  • PreCommit阶段:
  1. 协调者根据执行者的反应情况来决定是否可以进入第二阶段事务的PreCommit操作。
  2. 如果所有的执行者都返回Yes,则协调者向所有执行者发送PreCommit请求,并进入Prepared阶段,执行者接收到请求后,会执行事务操作,并将undo和redo信息记录到事务日志中,如果成功执行,则返回成功响应。
  3. 如果所有的执行者至少有一个返回No,则协调者向所有执行者发送abort请求,所有的执行者在收到请求或是超过一段时间没有收到任何请求时,会直接中断事务。
  • DoCommit阶段:

该阶段进行真正的事务提交。

  1. 协调者接收到所有执行者发送的成功响应,那么他将从PreCommit状态进入到DoCommit状态,并向所有执行者发送doCommit请求,执行者接收到doCommit请求之后,开始执行事务提交,并在完成事务提交之后释放所有事务资源,并最后向协调者发送确认响应,协调者接收到所有执行者的确认响应之后,完成事务(如果因为网络问题导致执行者没有收到doCommit请求,执行者会在超时之后直接提交事务,虽然执行者只是猜测协调者返回的是doCommit请求,但是因为前面的两个流程都正常执行,所以能够在一定程度上认为本次事务是成功的,因此会直接提交)
  2. 协调者没有接收至少一个执行者发送的成功响应(也可能是响应超时),那么就会执行中断事务,协调者会向所有执行者发送abort请求,执行者接收到abort请求之后,利用其在PreCommit阶段记录的undo信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源,执行者完成事务回滚之后,向协调者发送确认消息, 协调者接收到参与者反馈的确认消息之后,执行事务的中断。

相比两阶段提交,三阶段提交的优势是显而易见的,当然也有缺点:

  1.  3PC在2PC的第一阶段和第二阶段中插入一个准备阶段,保证了在最后提交阶段之前各参与节点的状态是一致的。
  2. 一旦参与者无法及时收到来自协调者的信息之后,会默认执行Commit,这样就不会因为协调者单方面的故障导致全局出现问题。
  3. 如果Commit时超时,此时协调者发送的是abort请求但是超时未接收,那么就会直接导致数据一致性问题。

3. 柔性事务TCC(补偿事务, Try-Confirm-Cancel)

根据需要,并不需要纯粹的2PC时,比如只关心数据的原子性和最终一致性,2PC的阻塞是不能忍受的,那就有聪明的人想到了一种新的方法,就是柔性事务TCC。

补偿事务TCC就是Try、Confirm、Cancel,它对业务有侵入性,一共分为三个阶段:

  • Try阶段:

两个微服务间同时进行Try,在Try的阶段会进行数据的校验,检查,资源的预创建。

比如我们需要在借书时,将书籍的库存-1,并且用户的借阅量也-1,但是这个操作,除了直接对库存和借阅量进行修改之外,还需要将减去的值,单独存放到冻结表中,但是此时不会创建借阅信息,也就是说只是预先把关键的东西给处理了,预留业务资源出来。

  •  Confirm阶段:

如果Try执行都成功无误,那么就进入到Confirm阶段,接着之前,我们就该创建借阅信息了,只能使用Try阶段预留的业务资源,如果创建成功,那么就对Try阶段冻结的值,进行解冻,整个流程就完成了。当然,如果失败了,那么进入到Cancel阶段。

  •  Cancel阶段:

如果Confirm时有一个服务有问题,则会转向Cancel,相当于进行Confirm的逆向操作。把冻结的东西还给人家,因为整个借阅操作压根就没成功。就像你付了款买了东西但是网络问题,导致交易失败,钱不可能不还给你吧。

跟XA协议相比,TCC就没有协调者这一角色的参与了,而是自主通过上一阶段的执行情况来确保正常,充分利用了集群的优势,性能也是有很大的提升。但是缺点也很明显,它与业务具有一定的关联性,需要开发者去编写更多的补偿代码,同时并不一定所有的业务流程都适用于这种形式。

整个柔性事务有多种实现的思想,例如:

TCC与2PC协议比较

  • TCC位于业务服务层而非资源层
  • TCC没有单独的准备(Prepare)阶段,Try操作兼备资源操作与准备能力
  • Try操作可以灵活选择业务资源的锁定粒度(以业务定粒度)
  • TCC有较高开发成本
  • 所谓的TCC编程模式,也是两阶段提交的一个变种。TCC就是通过代码人为实现了两阶段提交,不同的业务场景所写的代码都不一样,复杂度也不一样,因此,这种模式并不能很好地被复用。

Seata机制简介(附解决demo)

1.简介

Seata 的发展历程

阿里巴巴作为国内最早一批进行应用分布式(微服务化)改造的企业,很早就遇到微服务架构下的分布式事务问题。
阿里巴巴对于分布式事务问题先后发布了以下解决方案:

  1. 2014 年,阿里中间件团队发布 TXC(Taobao Transaction Constructor),为集团内应用提供分布式事务服务。
  2. 2016 年,TXC 在经过产品化改造后,以 GTS(Global Transaction Service) 的身份登陆阿里云,成为当时业界唯一一款云上分布式事务产品。在阿云里的公有云、专有云解决方案中,开始服务于众多外部客户。
  3. 2019 年起,基于 TXC 和 GTS 的技术积累,阿里中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback, FESCAR),和社区一起建设这个分布式事务解决方案。
  4. 2019 年 fescar 被重命名为了seata(simple extensiable autonomous transaction architecture)。
  5. TXC、GTS、Fescar 以及 seata 一脉相承,为解决微服务架构下的分布式事务问题交出了一份与众不同的答卷。

Seata 整体工作流程 

Seata 对分布式事务的协调和控制,主要是通过 XID 和 3 个
核心组件实现的。

XID:XID 是全局事务的唯一标识,它可以在服务的调用链路中传
递,绑定到服务的事务上下文中。

核心组件:

Seata 定义了 3 个核心组件:

  1. TC(Transaction Coordinator):即Seata服务器,是事务协调器,它是事务的协调者(这里指的是 Seata 服务器),主要负责维护全局事务和分支事务的状态,用于全局控制。驱动全局事务提交或回滚:比如在XA模式下就是一个协调者的角色,而一个分布式事务的启动就是由TM向TC发起请求,TC再来与其他的RM进行协调操作。
  2. TM(Transaction Manager):事务管理器,分布式事务的核心管理者。它是事务的发起者,负责定义全局事务的范围,并根据 TC 维护的全局事务和分支事务状态,做出开始事务、提交事务、回滚事务的决议。
  3. RM(Resource Manager):资源管理器,它是资源的管理者(这里可以将其理解为各服务使用的数据库)。它负责管理分支事务上的资源,向 TC 注册分支事务,汇报分支事务状态,驱动分支事务的提交或回滚, 即用于直接执行本地事务的提交和回滚。

以上三个组件相互协作,TC 以 Seata 服务器(Server)形式独立部署,TM 和 RM 则是以 Seata Client 的形式集成在微服务中运行,其整体工作流程如下图。

  

Seata 的整体工作流程如下:

  1. TM 向 TC 申请开启一个全局事务,全局事务创建成功后,TC 会针对这个全局事务生成一个全局唯一的 XID; 2. XID 通过服务的调用链传递到其他服务; 3. RM 向 TC 注册一个分支事务,并将其纳入 XID 对应全局事务的管辖;
  2. TM 根据 TC 收集的各个分支事务的执行结果,向 TC 发起全局事务提交或回滚决议;
  3. TC 调度 XID 下管辖的所有分支事务完成提交或回滚操作。

Seata支持4种事务模式

官网文档:Seata 是什么

  •  AT:本质上就是2PC的升级版,在 AT 模式下,用户只需关心自己的 “业务SQL”
  1. 一阶段,Seata 会拦截“业务 SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务 SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。
  2. 二阶段,如果确认提交的话,因为“业务 SQL”在一阶段已经提交至数据库, 所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可,当然如果需要回滚,那么就用“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理。 
  • TCC:和我们上面讲解的思路是一样的。
  • XA:同上,但是要求数据库本身支持这种模式才可以。

  • Saga:用于处理长事务,每个执行者需要实现事务的正向操作和补偿操作:

那么,以AT模式为例,我们的程序如何才能做到不对业务进行侵入的情况下实现分布式事务呢?实际上,Seata客户端,是通过对数据源进行代理实现的,使用的是DataSourceProxy类,所以在程序这边,我们只需要将对应的代理类注册为Bean即可(0.9版本之后支持自动进行代理,不用我们手动操作)

2.demo

2.1每个微服务加上依赖

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

2.2 每个微服务加上属性配置

seata:service:vgroup-mapping:# 这里需要对事务组做映射,默认的分组名为 应用名称-seata-service-group,将其映射到default集群# 这个很关键,一定要配置对,不然会找不到服务bookservice-seata-service-group: defaultgrouplist:default: localhost:8868

2.3 每个微服务启动类加上@EnableAutoDataSourceProxy注解

例如:

@EnableAutoDataSourceProxy
@SpringBootApplication
public class BookApplication {public static void main(String[] args) {SpringApplication.run(BookApplication.class, args);}
}

2.4 需要在开启分布式事务的方法上添加@GlobalTransactional注解:

例如:

@GlobalTransactional
@Override
public boolean doBorrow(int uid, int bid) {//这里打印一下XID看看,其他的服务业添加这样一个打印,如果一会都打印的是同一个XID,表示使用的就是同一个事务System.out.println(RootContext.getXID());if(bookClient.bookRemain(bid) < 1)throw new RuntimeException("图书数量不足");if(userClient.userRemain(uid) < 1)throw new RuntimeException("用户借阅量不足");if(!bookClient.bookBorrow(bid))throw new RuntimeException("在借阅图书时出现错误!");if(mapper.getBorrow(uid, bid) != null)throw new RuntimeException("此书籍已经被此用户借阅了!");if(mapper.addBorrow(uid, bid) <= 0)throw new RuntimeException("在录入借阅信息时出现错误!");if(!userClient.userBorrow(uid))throw new RuntimeException("在借阅时出现错误!");return true;
}

2.5 创建undo_log表

CREATE TABLE `undo_log`
(`id`            BIGINT(20)   NOT NULL AUTO_INCREMENT,`branch_id`     BIGINT(20)   NOT NULL,`xid`           VARCHAR(100) NOT NULL,`context`       VARCHAR(128) NOT NULL,`rollback_info` LONGBLOB     NOT NULL,`log_status`    INT(11)      NOT NULL,`log_created`   DATETIME     NOT NULL,`log_modified`  DATETIME     NOT NULL,`ext`           VARCHAR(100) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDBAUTO_INCREMENT = 1DEFAULT CHARSET = utf8;

更多推荐

微服务分布式事务介绍

本文发布于:2024-02-06 12:33:55,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1748782.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:分布式   事务

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!