Alibaba Seata

一.分布式事务

1.介绍

在微服务架构下,随着业务服务的拆分及数据库的拆分会存在如下图所示的场景,订单和库存分别拆分成了两个独立的数据库,当客户端发起一个下单操作时,需要在订单服务对应的数据库中创建订单,同时需要调用库存服务完成商品库存的扣减。

分布式事务 是指在分布式系统中,为了保证数据的一致性完整性,对多个节点上的数据进行操作的事务。当一个事务涉及到多个不同的数据库、服务或应用实例时,就构成了分布式事务。

比如上图,订单服务的数据操作和库存服务的数据操作保持一致(同时成功或同时失败),就是分布式事务的范畴。简单来说就是分布式数据一致性问题,也就是如何在分布式场景中保证多个节点数据的一致性。

举个例子,现在某一商品库存是充足的,但是某个用户的账户余额是不够的,此时客户端进行下单,对两个服务发送请求,库存验证发现充足,完成扣除库存;余额验证发现不充足,无法完成扣款,要提示下单失败。如果没有分布式事务,无法完成两个服务的同时回退,就会发生库存扣了,但是下单失败了,导致库存凭空消失。

2.X/Open 分布式事务模型

X/Open 是一个组织,X/Open DTP ( Distributed Transaction Process Reference Model) 是X/Open这个组织定义的一套分布式事务的标准。

这个标准提出了使用两阶段提交(2PC,Two-Phase-Commit) 来保证分布式事务的完整性。

这套标准主要定义了实现分布式事务的规范和API,具体的实现则交给相应的厂商来实现。

相关文档:DTP 参考模型

X/Open DTP参考模型包含三种角色:

|----|-----------------------------------------------------------|
| AP | Application,应用程序 |
| RM | Resource Manager,资源管理器,比如数据库。应用程序可以通过资源管理器对相应的资源进行有效的控制 |
| TM | Transaction Manager,事务管理器,一般指事务协调者,负责协调和管理各个子事务,可以理解为管理RM |

X/Open DTP模型的执行流程:

|------------------------------------------------------|
| 1. 配置TM,把多个RM注册到TM |
| 2. AP从TM管理的RM中获取连接,比如JDBC连接 |
| 3. AP向TM发起一个全局事务,生成全局事务ID(XID),XID会通知各个RM |
| 4. AP通过第二步获得的连接直接操作RM完成数据操作。AP在每次操作时会把XID传递给RM |
| 5. AP结束全局事务,TM会通知各个RM全局事务结束。根据各个RM的事务执行结果,执行提交或者回滚操作 |

3.两阶段提交

X/Open DTP 标准提出了使用两阶段提交(2PC,Two-Phase-Commit) 来保证分布式事务的完整性,在上图中也有体现。TM对多个RM事务的管理,就会涉及两个阶段的提交。第一个阶段是事务的准备阶段,第二个是事务的提交或者回滚阶段。

1)准备阶段(Prepare Phase)

协调者发送准备请求:协调者向所有参与者发送prepare 请求,询问它们是否准备好提交事务。这个请求包含了事务的详细信息,要求参与者对事务进行预处理,并准备好回滚或提交事务所需的所有资源。

参与者响应准备请求:参与者在收到 prepare 请求后,会执行事务操作,但不提交。如果参与者成功执行了事务操作,它会将事务的执行结果和准备状态记录在本地日志中,并向协调者发送 ready 消息,表示已经准备好提交事务。如果执行失败或无法准备,则向协调者发送 abort 消息。

2)提交阶段(Commit Phase)

协调者根据准备阶段的反馈进行决策:协调者收到所有参与者的响应后,会根据反馈结果做出决策。如果所有参与者都返回 ready ,则协调者决定提交事务。如果有任何一个参与者返回 abort,则协调者决定回滚事务。

协调者发送提交或回滚请求:

提交事务:如果协调者决定提交事务,它会向所有参与者发送 commit 请求。参与者在收到 commit 请求后,会正式提交事务,并释放所有资源,然后向协调者发送 ack消息,表示事务已成功提交。

回滚事务:如果协调者决定回滚事务,它会向所有参与者发送 rollback 请求。参与者在收到 rollback 请求后,会回滚事务,并释放所有资源,然后向协调者发送 ack消息,表示事务已成功回滚。

两阶段提交把一个事务的处理过程分为准备和提交/回滚两个阶段,采用简单的方式来解决分布式事务的问题,但是这个过程中,存在以下缺点:

|-------|---------------------------------------------------------------------------------------------------------------------------------|
| 阻塞问题 | 两个阶段都是事务阻塞型的,对于每一个指令都需要有明确的响应,如果在这个过程中,TM宕机或者网络出现故障,则会一直处于阻塞状态。比如第一阶段完成后TM宕机或网络出现故障了,此时RM会一直阻塞,无法进行其他操作。所以3PC针对此问题,加入了timeout机制 |
| 资源占用 | 参与者在收到准备请求后,会锁定相关资源以保证事务的原子性。在整个两阶段提交过程中, 这些资源一直被锁定,直到事务提交或回滚完成。这会导致资源利用率降低,其他事务可能因无法获取所需资源而等待 |
| 数据不一致 | 第二阶段中,TM向所有的RM发送commit请求,由于局部网络异常,导致只有一部分RM收到了commit请求,这些RM节点执行commit操作,没有收到commit请求的节点由于事务无法提交,出现数据不一致的情况 |

相应也存在以下优点:

|----------|-----------------------------------------------|
| 保证事务的原子性 | 2PC通过两个阶段的严格控制,确保了事务要么全部提交,要么全部回滚,从而保证了事务的原子性 |
| 实现相对简单 | 相对于其他分布式事务协议,2PC的实现相对简单,易于理解和实现 |

4.三阶段提交

3PC(Three-Phase-Commit),是2PC的改进版本,共分为 CanCommit,PreCommit 和 DoCommit三个阶段。

1)CanCommit 阶段

协调者发起请求:协调者向所有参与者发送 CanCommit 请求,询问它们是否可以执行事务提交操作。此阶段不涉及实际的数据修改,只是确认每个参与者是否有足够的资源和条件来完成事务。

参与者响应:参与者根据自身情况返回YesNo 。如果所有参与者都返回Yes ,则进入PreCommit阶段。

2)PreCommit 阶段

协调者发送 PreCommit 请求:协调者向所有参与者发送 PreCommit请求,询问是否可以进行事务的预提交操作。

参与者准备事务:参与者执行事务操作,并将事务执行结果和准备状态(Yes/No)发送给协调者。参与者会记录预提交日志,并确保这些日志是持久化的。

协调者收集反馈并决策:如果所有参与者都返回Yes ,则进入 DoCommit 阶段。如果有任何一个参与者返回No 或超时未响应,协调者会发送 abort请求,通知所有参与者回滚事务。

3)DoCommit 阶段

协调者发送 DoCommit 请求:协调者向所有参与者发送 DoCommit请求,指示它们正式提交事务。

参与者执行提交:参与者收到 DoCommit 请求后,执行事务提交操作,并向协调者发送 Ack消息,表示事务已提交。

超时机制:如果参与者在等待 DoCommit请求时超时,会默认执行提交操作。

优点:

|--------|------------------------------------------------------------------|
| 减少阻塞 | 3PC通过引入超时机制,减少了2PC中的阻塞问题。避免了资源被永久锁定 |
| 增强容错能力 | 即使协调者在DoCommit阶段之前出现故障,参与者也可以基于其预提交的状态自主决定继续提交或回滚事务,从而减少了对协调者的依赖 |

缺点:

|---------|-------------------------------------------------------------------------------------|
| 实现复杂度高 | 3PC的实现比2PC更复杂,增加了系统的开发和维护成本 |
| 数据不一致风险 | 在某些情况下,如网络分区,参与者在收到 PreCommit 消息后,如果网络出现故障,协调者和参与者无法进行后续通信,参与者在超时后可能会自行提交事务,导致数据不一致 |

5.TCC事务

TCC(Try-Confirm-Cancel)是一种分布式事务解决方案,是由Pat Helland在2007年发表的论文《Life beyond Distributed Transactions: An Apostate's Opinion》中提出。TCC事务相对于传统两阶段,其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对 (由业务系统提供的 ) 业务逻辑的接口调用来实现分布式事务。

TCC 通过将事务操作拆分为三个阶段:

1)Try 阶段:尝试执行业务操作,完成所有业务检查,并预留必要的业务资源。这个阶段不真正执行事务,只是进行资源的预占;

2)Confirm 阶段:如果所有参与者在Try阶段都成功,那么进入 Confirm 阶段,正式完成操作,使用之前预留的资源;

3)Cancel 阶段:如果任何一个参与者在Try阶段失败,那么进入 Cancel 阶段,所有参与者回滚在Try阶段执行的操作,释放预留的资源。

TCC事务属于两阶段提交思想的变体,它在设计上借鉴了两阶段提交的核心理念,第一阶段通过Try进行准备工作,第二阶段Confirm/Cancel表示Try阶段操作的确认和回滚。

在主业务方式中,会先调用业务服务对外提供的 Try 方式来做资源预留,如果业务服务 Try 方法处理都正常,TCC事务协调器就会调用 Confirm 方法对预留资源进行实际应用。否则就会调用各个服务的Cancel 方法进行回滚,从而保证数据的一致性。

优点:

|---------------------------------------------|
| 无需依赖第三方中间件或数据库来实现分布式事务,降低了系统复杂度和成本 |
| 无需锁定全局资源,提高了系统的并发性能和可用性 |
| 适用于各种类型的业务场景,只要能够定义出清晰的Try、Confirm和Cancel逻辑 |

缺点:

|----------------------------------------------|
| 需要开发人员手动编写三个阶段的业务逻辑,并保证其正确性和一致性,增加了开发难度和维护成本 |
| 需要考虑各种异常情况和边界情况,并提供相应的补偿策略和重试机制,增加了系统复杂度和风险 |

二.Seata

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

详细请看官网:Seata 是什么? | Apache Seata

1.术语

1)TC (Transaction Coordinator) - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚

2)TM (Transaction Manager) - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务

3)RM (Resource Manager) - 资源管理器

管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚

2.下载和部署

下载

下载地址:Seata Java Download | Apache Seata

修改配置

在修改配置前,先去**/seata-server/script/server/db/mysql.sql** 找到这个SQL文件,并执行里面的内容:

sql 复制代码
CREATE DATABASE IF NOT EXISTS seata;

修改 /seata-server/conf/application.yml 中seata相关的配置:

复制代码
seata:
  config:
    # support: nacos, consul, apollo, zk, etcd3
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: ''
      group: SEATA_GROUP
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
  store:
    # support: file, db, redis, raft
    mode: db
    db:
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true
      user: root
      password: root
      min-conn: 10
      max-conn: 100
      global-table: global_table
      branch-table: branch_table
      lock-table: lock_table
      distributed-lock-table: distributed_lock
      vgroup-table: vgroup_table
      query-limit: 1000
      max-wait: 5000

启动

双击 /seata-server/bin/seata-server.bat

访问 http://127.0.0.1:7091/,用户名密码:seata/seata

3.集成

1)引入依赖

XML 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

2)修改配置文件

XML 复制代码
seata:
  registry: #定义了Seata Server的注册中⼼配置, 微服务根据配置信息去注册中⼼获取tc服务地址
    type: nacos #指定注册中心的类型
    nacos:
      application: seata-server #Seata Server在Nacos中的应⽤名称
      server-addr: 127.0.0.1:8848 #Nacos服务器地址
      group: "SEATA_GROUP" #Seata Server在Nacos中的分组名称
      namespace: "" #Nacos的命名空间, 设置为空, 表⽰使⽤默认的命名空间public
  tx-service-group: default_tx_group #定义事务服务组的名称
  service:
    vgroup-mapping:
      default_tx_group: default

微服务启动时,会根据 default_tx_group 查找Seata Server. Seata Server在启动时会注册到Nacos的 SEATA_GROUP 分组中,应用名称为 seata-server ,并映射到 default 集群。这样,Seata Client可以通过Nacos发现并连接到Seata Server,进行事务协调和管理。

三.Seata各事务模式

1.XA 模式

XA 模式是从 1.2 版本支持的事务模式。XA 规范 是 X/Open 组织定义的分布式事务处理标准。 Seata XA模式是利用事务资源(数据库、消息服务等)对 XA 协议的支持,以 XA 协议的机制来管理分支事务的一种事务模式。

XA实现的原理是基于两阶段提交。

优点:

|------------|-----------------------------------------------|
| 事务强一致性 | XA模式能够满足ACID原则,确保分布式事务的强一致性 |
| 实现简单且无代码侵入 | 常用数据库都支持XA协议,使用Seata的XA模式无需修改业务代码,只需进行简单的配置即可 |

缺点:

|----------|-----------------------------------------------------|
| 性能较差 | 一阶段需要锁定数据库资源,等待二阶段结束才释放,导致事务资源长时间得不到释放,锁定周期长,从而影响性能 |
| 依赖关系型数据库 | XA模式依赖数据库实现事务,对于一些非关系型数据库或不支持XA协议的数据库,无法使用 |

2.AT 模式

AT 模式是 Seata 创新的一种非侵入式的分布式事务解决方案。Seata 在内部做了对数据库操作的代理层,我们适用 Seata AT 模式时,实际上用的是 Seata 自带的数据源代理 DataSourceProxy,Seata 在这层代理中加入了很多逻辑,比如插入回滚 undo_log 日志,检查全局锁等。

3.TCC 模式

TCC 模式是 Seata 支持的一种由业务方细粒度控制的侵入式分布式事务解决方案,是继 AT 模式后第二种支持的事务模式,最早由蚂蚁金服贡献。其分布式事务模型直接作用于服务层,不依赖底层数据库,可以灵活选择业务资源的锁定粒度,减少资源锁持有时间,可扩展性好,可以说是为独立部署的 SOA 服务而设计的。

4.Saga 模式

Saga 模式是 SEATA 提供的长事务解决方案,在 Saga 模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。

5.四种模式对比

|-------|-----------------------------------------------------------------|---------------------------------------------------------------------|-------------------------------|--------------------------------------|
| | XA | AT | TCC | SAGA |
| 实现方式 | 依赖数据库对XA协议的支持,通过XA规范来实现事务的提交和回滚; 不需要额外的 undo_log 表,但要求数据库支持XA协议 | 通过记录数据快照 ( undo_log 表 ) 来实现数据的回滚; 适用于几乎所有的数据库,但需要在业务库中创建 undo_log 表 | 开发人员手动实现Try、Confirm、Cancel三阶段 | 事件驱动,每个事务包含正向操作和逆向补偿操作; 失败时按顺序执行逆向补偿 |
| 一致性 | 强一致性 事务的中间状态对用户不可见 | 最终一致性 在事务的两阶段之间,数据可能处于中间状态 | 最终一致性(通过业务实现) | 最终一致性 |
| 性能 | 性能较差,一阶段锁定资源,等待二阶段结束才释放 | 性能较好,一阶段直接提交,不锁定资源 | 较高,但开发成本高(需要处理空回滚,业务悬挂等) | 高(无锁) 适合长事务 |
| 代码侵入 | 无代码侵入 | 无代码侵入 | 有,需要手动编写三个接口 | 有,需要编写状态机和补偿业务 |
| 数据库支持 | 依赖数据库对XA协议的支持 | 适用于几乎所有支持SQL的数据库 | 不依赖底层数据库的事务机制 | 不依赖底层数据库的事务机制 |

相关推荐
fanly1119 小时前
Surging AI Agent 完整产品介绍
微服务·microservice
蝎子莱莱爱打怪7 天前
XZLL-IM干货系列 04|Netty 长连接实战:Pipeline 怎么排、心跳怎么跳、连接怎么管
后端·微服务·面试
SamDeepThinking8 天前
Java微服务练习方式
java·后端·微服务
米丘11 天前
微前端之 Web Components 完全指南
微服务·html
霸道流氓气质14 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
霸道流氓气质14 天前
Spring Boot 微服务性能优化完全指南
spring boot·微服务·性能优化
地瓜伯伯14 天前
从MESI缓存一致性协议讲透synchronized的底层
java·spring boot·spring·spring cloud·微服务·springcloud
Devin~Y14 天前
大厂 Java 面试实录:从音视频内容社区到 AI RAG 的全链路技术设计
java·spring boot·redis·spring cloud·微服务·kafka·音视频
递归尽头是星辰14 天前
AI 访问数据仓库:从直连到微服务化
数据仓库·人工智能·微服务·dataagent·ai数据治理
就改了15 天前
Windows 环境 SkyWalking 完整实操教程
windows·微服务·skywalking