安装Seata

下载Seata Server安装包

Seata 安装包的下载网址为网址7,本书选择的版本是 1.4.2,下载网址为网址8。

选择 Seata 1.4.2 版本的原因主要是参考了官方组件版本的对应关系,本书中所使用的 Spring Cloud Alibaba 的版本为 2021.0.1.0,官方推荐 Spring Cloud Alibaba 2021.0.1.0 对应的 Nacos 版本为 1.4.2

下载成功后,会得到一个名称为 seata-server-1.4.2.zip 的文件,解压缩后的目录结构如下。

  • bin:存放启动 Seata Server 的脚本文件。

  • confSeata Server 的配置目录。

  • libSeata ServerJar 包存放目录。

  • logs:存放日志文件。

下载并解压缩后,还需要对关键配置做一些更改。

Seata Server 的持久化配置

Seata Server 作为全局事务的管理者,需要记录和存储一些数据,因此需要存储介质来做数据持久化的工作。

Seata 支持 filedbredis 三种持久化模式。file 是本地文件;db 是数据库,如 MySQLOracleOceanBase 等;redis 就是使用 Redis 作为存储介质。默认情况下,Seata 使用本地文件来做持久化工作,本地文件的方式不适合后期 Seata Server 的集群拓展,因此建议把 Seata Server 持久化方案修改为 dbredis 的方式。本书使用 MySQL 来做 Seata Server 的持久化工作。接下来是具体的操作流程。

Seata 安装目录下的 conf 文件夹中,有一个名称为 file.conf 的文件,这个文件就是用来配置 Seata Server 持久化方式的。打开这个文件,并做如下修改。

  1. 修改存储方式。

    mode 配置项修改为 db,代码如下:

    store {
      ## store mode: file、db、redis
      mode = "db"
    }
  2. 配置 MySQL 的连接信息。

    相关的配置项同样是在 file.conf 文件中,只需要把数据库地址、登录用户和登录密码修改成自己的,其他配置项使用默认设置即可。最终配置内容如下:

    # transaction log store, only used in seata-server
    store {
      # store mode: file, db, redis
      mode = "db"
    
      # database store property
      db {
        # the implement of javax.sql.DataSource, such as DruidDataSource (druid)/
        # BasicDataSource (dbcp) / HikariDataSource (hikari) etc.
        datasource = "Druid"
        # mysql/oracle/postgresql/h2/oceanbase etc.
        dbType = "mysql"
        driverClassName = "com.mysql.cj.jdbc.Driver"
        # if using mysql to store the data, recommend add
        rewriteBatchedStatements=true in jdbc connection param
    
        # 修改为自己的数据库地址链接,数据库名称为 seata_server_db (可自行定义)
        url = "jdbc:mysql://127.0.0.1:3306/seata_server_db?rewriteBatchedStatements=
    true&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false"
        # 修改为自己的数据库登录用户
        user = "root"
        # 修改为自己的数据库登录密码
        password = "123456"
        minConn = 5
        maxConn = 100
        globalTable = "global_table"
        branchTable = "branch_table"
        lockTable = "lock_table"
        queryLimit = 100
        maxWait = 5000
      }
    }
  3. 新建数据库并创建表结构。

打开数据库操作工具,新建 seata_server_db 数据库,之后导入 Seata Server 所需的表结构。具体的建表语句 Seata 官方已经提供了,见网址9。

最终的建库、建表 SQL 内容如下:

# 新建 seata_server 数据库
CREATE DATABASE /*!32312 IF NOT EXISTS*/`seata_server_db` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `seata_server_db`;

# 以下语句是官方提供的
-- 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 NOT NULL,
  `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'),
    KEY 'idx_xid_and_branch_id' ('xid', '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 ('AsyncCommitting', '', 0);
INSERT INTO 'distributed_lock' (lock_key, lock_value, expire) VALUES
('RetryCommitting', '', 0);
INSERT INTO 'distributed_lock' (lock_key, lock_value, expire) VALUES
('RetryRollbacking', '', 0);
INSERT INTO 'distributed_lock' (lock_key, lock_value, expire) VALUES
('TxTimeoutCheck', '', 0);

当然,这些字段的定义中某些参数是可以根据自身系统进行修改的。比如,lock_table 表中的 table_name 字段,部分业务表的表名太长导致超出了 32 个字符长度,在执行分布式事务流程时就会报错。那么,在建表时就可以把这个字段的长度增加,如 VARCHAR(64)VARCHAR(128),这一点需要格外注意。

直接导入 seata_server_db 数据库即可,导入成功后的数据库结构如图 10-18 所示。

image 2025 04 18 10 33 35 751
Figure 1. 图10-18 seata_server_db 数据库结构

另外,读者需要注意的一点是,这个数据库与微服务中的数据库并没有什么关系,只需要把数据库当作 Seata Server 中间件的一部分即可。