SpringCloudAlibaba篇(六)整合Seata(微服务分布式事务nacos+seata)

1,152 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Seata 是什么?

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

AT 模式

前提

  • 基于支持本地 ACID 事务的关系型数据库。
  • Java 应用,通过 JDBC 访问数据库。

整体机制

两阶段提交协议的演变:

  • 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
  • 二阶段:
    • 提交异步化,非常快速地完成。
    • 回滚通过一阶段的回滚日志进行反向补偿。

seata官方文档

项目整合seata

1.拉取并运行seata服务端

1.1 拉取seata

github.com/seata/seata… 在这里插入图片描述

1.2 修改配置

在这里插入图片描述 参考文档修改conf/registry.conf,配上自己的nacos 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 注意将type 修改为nacos ,建议新建一个namespace 如何新建因为配置文件实在是太多了

1.3 下载配置文件

config.txt下载 在这里插入图片描述

修改存储模式 在这里插入图片描述

修改连接池信息

我的mysql是8.0的所以 store.db.driverClassName=com.mysql.jdbc.Driver 
需要修改为store.db.driverClassName=com.mysql.cj.jdbc.Driver

在这里插入图片描述

1.4 下载seata数据库的建表SQL

github.com/seata/seata…

数据库中新建seata数据库 并执行 mysql.sql
-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(
    `xid`                       VARCHAR(128) NOT NULL,
    `transaction_id`            BIGINT,
    `status`                    TINYINT      NOT NULL,
    `application_id`            VARCHAR(32),
    `transaction_service_group` VARCHAR(32),
    `transaction_name`          VARCHAR(128),
    `timeout`                   INT,
    `begin_time`                BIGINT,
    `application_data`          VARCHAR(2000),
    `gmt_create`                DATETIME,
    `gmt_modified`              DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_status_gmt_modified` (`status` , `gmt_modified`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(128),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `status`         TINYINT      NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_status` (`status`),
    KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

CREATE TABLE IF NOT EXISTS `distributed_lock`
(
    `lock_key`       CHAR(20) NOT NULL,
    `lock_value`     VARCHAR(20) NOT NULL,
    `expire`         BIGINT,
    primary key (`lock_key`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('HandleAllSession', ' ', 0);

1.5 下载向nacos推送配置的脚本

github.com/seata/seata… 在这里插入图片描述

  • 将config.txt 文件放置到根目录 在这里插入图片描述
  • nacos-config.sh文件放到conf目录下 在这里插入图片描述

1.6 向nacos推送配置

这里我用一下git bash here执行shell脚本 在这里插入图片描述 执行命令

sh nacos-config.sh -h 127.0.0.1 -p 8848 -g SEATA_GROUP -t seata -u nacos -p nacos
# h: nacos服务ip.
# p: nacos服务端口号.
# g: 想要的分组信息.
# t: 第一步新建的命名空间.
# u: nacos登录名.
# w: nacos登录密码

在这里插入图片描述

推送完毕,我们这里可以看出这个是一行配置创建了一个文件,以后修改配置就不用脚本推送了, 直接在nacos中修改即可,
前提是你在registry.conf文件中配置了nacos

在这里插入图片描述

1.7 启动seata-server

  • 执行/bin/seata-server.bat 在这里插入图片描述

  • 启动完成 在这里插入图片描述

2. 配置客户端

2.1 添加依赖

版本已在父工程中定义了参数,详见 SpringCloudAlibaba篇(一)搭建父工程,并初始化推送到git仓库 <alibaba.seata.version>1.4.2</alibaba.seata.version>

service-starter-parent工程中添加依赖 , 
service-starter-parent是所有微服务依赖的一个pom微服务模块,
微服务添加依赖直接在service-starter-parent中添加即可。

搭建service-starter-parent 详见 SpringCloudAlibaba篇(二)整合Nacos注册配置中心 pom.xml

<!-- seata -->
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>${alibaba.seata.version}</version> 1.4.2
</dependency>

2.2 配置seata

  • nacos中新建seata-client.yaml 在这里插入图片描述
seata:
  enabled: true
  application-id: seata-service
  tx-service-group: default_tx_group
  enable-auto-data-source-proxy: true
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: seata
      group: SEATA_GROUP
      username: nacos
      password: nacos
  registry:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: seata
      application: seata-server
      group: SEATA_GROUP
      username: nacos
      password: nacos
  • bootstrap.yml 追加 在这里插入图片描述

2.3 添加表

每个参与分布式事务的数据库都需要加该表
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
    `branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(128) NOT NULL COMMENT 'global transaction id',
    `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
    `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',
    `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',
    `log_created`   DATETIME(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';

2.4 启动

在这里插入图片描述 在方法上添加@GlobalTransactional 即可开启分布式事务 详见seata官方文档 后续有时间我会自己测试

  • timeoutMills 超时时间-毫秒 默认60000ms 在这里插入图片描述
  • name 事务组名称默认default 在这里插入图片描述

脚本说明

client

存放用于客户端的配置和SQL

  • at: AT模式下的 undo_log 建表语句
  • conf: 客户端的配置文件
  • saga: SAGA 模式下所需表的建表语句
  • spring: SpringBoot 应用支持的配置文件

server

存放server侧所需SQL和部署脚本

  • db: server 侧的保存模式为 db 时所需表的建表语句
  • docker-compose: server 侧通过 docker-compose 部署的脚本
  • helm: server 侧通过 Helm 部署的脚本
  • kubernetes: server 侧通过 Kubernetes 部署的脚本

config-center

用于存放各种配置中心的初始化脚本,执行时都会读取 config.txt配置文件,并写入配置中心

  • nacos: 用于向 Nacos 中添加配置
  • zk: 用于向 Zookeeper 中添加配置,脚本依赖 Zookeeper 的相关脚本,需要手动下载;ZooKeeper相关的配置可以写在 zk-params.txt 中,也可以在执行的时候输入
  • apollo: 向 Apollo 中添加配置,Apollo 的地址端口等可以写在 apollo-params.txt,也可以在执行的时候输入
  • etcd3: 用于向 Etcd3 中添加配置
  • consul: 用于向 consul 中添加配置