安装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
的脚本文件。 -
conf
:Seata Server
的配置目录。 -
lib
:Seata Server
的Jar
包存放目录。 -
logs
:存放日志文件。
下载并解压缩后,还需要对关键配置做一些更改。
Seata Server 的持久化配置
Seata Server
作为全局事务的管理者,需要记录和存储一些数据,因此需要存储介质来做数据持久化的工作。
Seata
支持 file
、db
、redis
三种持久化模式。file
是本地文件;db
是数据库,如 MySQL
、Oracle
、OceanBase
等;redis
就是使用 Redis
作为存储介质。默认情况下,Seata
使用本地文件来做持久化工作,本地文件的方式不适合后期 Seata Server
的集群拓展,因此建议把 Seata Server
持久化方案修改为 db
或 redis
的方式。本书使用 MySQL
来做 Seata Server
的持久化工作。接下来是具体的操作流程。
在 Seata
安装目录下的 conf
文件夹中,有一个名称为 file.conf
的文件,这个文件就是用来配置 Seata Server
持久化方式的。打开这个文件,并做如下修改。
-
修改存储方式。
将
mode
配置项修改为db
,代码如下:store { ## store mode: file、db、redis mode = "db" }
-
配置
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 } }
-
新建数据库并创建表结构。
打开数据库操作工具,新建 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 所示。

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