Seata 分布式事务搭建与使用详解,一篇搞定,手把手教会你 !


1. Seata是什么?

Seata 是一款开源的分布式事务解决方案,致力于提供高性能简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和XA 事务模式,为用户打造一站式的分布式解决方案。AT模式是阿里首推的模式,阿里云上有商用版本的GTS(Global Transaction Service 全局事务服务)。

2. Seata的三大角色

在 Seata 的架构中,一共有三个角色:

  • TC (Transaction Coordinator) - 事务协调者
    维护全局和分支事务的状态,驱动全局事务提交或回滚。
  • TM (Transaction Manager) - 事务管理器
    定义全局事务的范围:开始全局事务、提交或回滚全局事务。
  • RM (Resource Manager) - 资源管理器
    管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

其中,TC 为单独部署的 Server 服务端,TM 和 RM 为嵌入到应用中的 Client 客户端。

3. AT 模式介绍

AT 模式是一种无侵入的分布式事务解决方案。阿里 Seata 框架,实现了该模式。
在 AT 模式下,用户只需关注自己的“业务 SQL”,用户的 “业务 SQL” 作为一阶段,Seata 框架会自动生成事务的二阶段提交和回滚操作。

3.1 AT模式实现说明

  • 一阶段:

    • Seata 会拦截" 业务SQL",解析 SQL 语义
    • 查询 “业务SQL” 要更新的业务数据,在业务数据被更新前,将其保存成 “before image
    • 执行 “业务SQL” ,更新业务数据
    • 查询更新后的数据,将其保存成 “after image
    • 将 before image 和 after image 保存至 Undo Log 表中
    • 生成行锁
      以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。
      在这里插入图片描述
  • 二阶段(提交):

    • 因为 “业务SQL” 在一阶段已经提交至数据库,所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可。
      在这里插入图片描述
  • 二阶段(回滚):

    • 首先要校验脏写,对比“数据库当前业务数据”和 “after image”
      • 如果两份数据完全一致就说明没有脏写,可以还原业务数据。
      • 如果不一致就说明有脏写,出现脏写就需要转人工处理。
    • 用“before image”还原业务数据
    • 删除快照数据和行锁

在这里插入图片描述

3.2 实例说明

下单操作中包含 对订单服务与库存服务的操作,分别修改订单状态,与库存数量。示例图如下:

在这里插入图片描述


4. 设计亮点

相比与其它分布式事务框架,Seata架构的亮点主要有几个:

  1. 应用层基于SQL解析实现了自动补偿,从而最大程度的降低业务侵入性;
  2. 将分布式事务中TC(事务协调者)独立部署,负责事务的注册、回滚;
  3. 通过全局锁实现了写隔离与读隔离。

5. Seata 快速开始

5.1 Seata Server(TC)环境搭建

5.1.1 下载安装包

链接: https://github.com/seata/seata/releases

注意:选择的 Seata 版本最好要与 Spring Cloud 版本相匹配
链接: spring-cloud-alibaba 版本说明文档
在这里插入图片描述

本文使用 Windos环境下的 seata-server-1.3.0 进行部署说明:

在这里插入图片描述

5.1.2 事务信息存储配置

Server 端存储模式(store.mode)支持三种方式:

  • file:单机模式(默认为此模式),全局事务会话信息存储在内存中,读写并持久化至本地文件 root.data (bin\sessionStore\root.data) 中,性能较高。
  • db高可用模式(Mysql 5.7+),全局事务会话信息通过db共享,相应性能差些。
  • redis:Seata-Server 1.3及以上版本支持,性能较高,但存在事务信息丢失风险,请提前配置适合当前场景的redis持久化配置。

本文选用 db模式进行配置说明:

  • 打开 conf/file.conf 文件
  • 修改 mode = “db”
  • 修改数据库连接信息(url\user\password),如下图所示:
    在这里插入图片描述
  • 创建数据库 seata-server
  • 新建表:可以去seata提供的资源信息中下载:

后续配置中会用到 config-center/config.txtconfig-center/nacos/nacos-config.sh 两个文件,可以选择直接复制其内容并定义相同名称,也可把script 文件夹下载下来。

在这里插入图片描述
- 运行 server\db\mysql.sql 文件:
global_table:存储全局事务的信息
branch_table:存储事务参与者的信息
lock_table:存储锁信息(锁的表信息,行信息)

5.1.3 Nacos(注册&配置中心)配置

  • 将Seata Server注册到Nacos,并配置到配置中心
    打开 conf/registry.conf,修改conf目录下的registry.conf配置:
    在这里插入图片描述

注意:如果配置了seata server使用nacos作为配置中心,则配置信息会从nacos读取,file.conf可以不用配置。 客户端配置registry.conf
使用nacos时也要注意group要和seata server中的group一致,默认group是"DEFAULT_GROUP"

  • 启动注册中心 Nacos Server
    Nacos 单机或集群模式下都可以:

    1. 单机模式:后续的配置默认 seata 连接 nacos 端口为 8848;
    2. 集群模式:以 nginx 配置的端口为准,本文使用的端口为 8847;
  • 配置Nacos 配置中心
    获取/seata/script/config-center/config.txt 文件,修改配置信息,如下图:

    1. 修改数据库相关配置
      在这里插入图片描述
    2. 配置事务分组
      service.vgroupMapping.my_test_tx_group=default
    • my_test_tx_group:需要与客户端保持一致 ,可以自定义(projectA、projectB…)
      (客户端properties配置:spring.cloud.alibaba.seata.tx‐service‐group=my_test_tx_group)
    • default:需要跟客户端和registry.conf中registry中的cluster保持一致 (即5.1.3的第一步配置)
      default 必须要等于 registry.conf cluster = “default”

    事务分组主要可以解决:异地机房停电问题,提高容错
    在这里插入图片描述

5.1.4 Seata 配置文件注册至 Nacos 配置中心

  • 下载Git,Windows 环境需有此工具,才可运行 .sh 文件,安装成功如下图:
    在这里插入图片描述
  • 获取 /seata/script/config-center/nacos/nacos-config.sh 文件:考虑到用户复制文件与直接下载 script 文件夹 两种情况
    • 直接复制文件使用,如下图:
      在这里插入图片描述
      注意!!! 需要修改 nacos-config.sh 文件 86 行代码,用以获取 config.txt 文件。
      在这里插入图片描述
    • 下载整个 script 文件夹,复制到 bin 同级目录下,无需修改 nacos-config.sh 文件,如下图:
      在这里插入图片描述
  • 运行 nacos-config.sh
// 运行指令 ,通过 Git Bash Here
sh nacos‐config.sh ‐h localhost ‐p 8848 -u nacos -w nacos ‐g SEATA_GROUP ‐t 5a3c7d6c‐f497‐4d68‐a71a‐2e5e3340b3ca

参数说明:
-h: host,默认值 localhost
-p: port,默认值 8848
-u: nacos用户名
-w: nacos密码
-g: 配置分组,默认值为 ‘SEATA_GROUP’
-t: 租户信息,对应 Nacos 的命名空间ID字段, 默认值为空 ‘’

在这里插入图片描述
成功结果如下图所示:
在这里插入图片描述

5.1.5 启动 Seata Server

  • 单体环境:双击 seata-server.bat 即可
    启动成功,默认端口 8091,如下图所示:
    在这里插入图片描述
  • 集群环境:命令启动,需在 Linux 环境下
bin/seata-server.sh -h 127.0.0.1 -p 8091 -m db -n 1 -e test

启动参数说明:

参数全写作用备注
-h–host指定在注册中注册的IP不指定时获取当前的IP,外部访问部署在云环境和容器中的server,建议指定
-p–port指定server 启动的端口默认为8091
-m–storeMode事务日志存储方式支持 file,db,redis,默认为file。注:redis需 seata-server 1.3 版本及以上
-n–serverNode用于指定seata-server节点ID如 1,2,3 … ,默认为 1
-e–seataEnv指定seata-server运行环境如 dev,test 等,服务启动时会使用 registry-dev.conf 这样的配置

bin/seata-server.sh -p 8091 -n 1
bin/seata-server.sh -p 8092 -n 2
bin/seata-server.sh -p 8093 -n 3


5.2 Seata Client 代码实现

声明式事务实现添加(@GlobalTransactional)
接入微服务应用
业务场景:
用户下单,整个业务逻辑由三个微服务构成,如下图所示:
        订单服务:根据采购需求创建订单。
        库存服务:对给定的商品扣除库存数量
在这里插入图片描述

5.2.1 启动Seata server端,Seata server使用nacos作为配置中心和注册中心(上一步已完成)

5.2.2 配置微服务整合seata

  • 添加pom 依赖
	<dependencies>
        <!--nacos 服务注册与发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--导入openfeign 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

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

        <!-- skywalking 工具类 可自定义链路追踪,跟服务版本一致-->
        <dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-toolkit-trace</artifactId>
            <version>8.12.0</version>
        </dependency>
    </dependencies>
  • 在各微服务对应数据库中添加 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,
 PRIMARY KEY (`id`),
 UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
  • 修改application.yml配置
  1. 添加事务分组
    tx-service-group: my_test_tx_group
详情说明:
 参考 5.1.3 Nacos(注册&配置中心)配置 ---->配置Nacos 配置中心-----> 配置事务分组 说明
 
 my_test_tx_group:需要与客户端保持一致 ,可以自定义(projectA、projectB…)
(客户端properties配置:spring.cloud.alibaba.seata.tx‐service‐group=my_test_tx_group)
  1. 配置 seata 的注册中心, 告诉 seata client 怎么去访问 seata server 事务协调者进行通信
  2. 配置 seata 的配置中心,可以读取关于 seata client 的一些配置,即 “seata\seata\script\config-center\config.txt” 中的配置

具体yaml 配置如下:

spring:
  application:
    name: seata-order
  datasource:
    url: jdbc:mysql://172.16.10.132:3306/seata_order?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      server-addr: 172.16.10.132:8847 # 此处通过 nginx进行通信
      discovery:
        username: nacos
        password: nacos
    alibaba:
      seata:
        tx-service-group: my_test_tx_group # 配置事务分组,在 "seata\seata\script\config-center\config.txt" 中设置
server:
  port: 8070
seata:
  registry: # 注册中心
    # 配置 seata 的注册中心, 告诉 seata client 怎么去访问 seata server 事务协调者进行通信
    type: nacos
    nacos:
      server-addr: 172.16.10.132:8847 # seata-server 所在的注册中心地址
      application: seata-server # 指定 seata-server 在注册中心的 服务名, (默认 seata-server)
      username: nacos
      password: nacos
      group: SEATA_GROUP # 默认 SEATA_GROUP
  config:
    # 配置 seata 的配置中心,可以读取关于 seata client 的一些配置,即 "seata\seata\script\config-center\config.txt" 中的配置
    type: nacos
    nacos: # 配置中心
      server-addr: 172.16.10.132:8847
      username: nacos
      password: nacos
      group: SEATA_GROUP
  • 在启动类或方法上添加 @GlobalTransactional 即可

总结

以上步骤都完成后,就实现了 Seata 分布式事务的搭建与使用,希望这篇文章能对你们有所帮助。

  • 41
    点赞
  • 242
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值