SprinrBoot整合Seata使用AT模式解决多数据源分布式事务
分布式事务场景:
1.应用中使用多数据源,跨多个数据库
2.跨多个应用进程
Seata是阿里巴巴开源的分布式事务中间件,以高效并且对业务0 侵入的方式,解决微服务场景下面临的分布式事务问题。
Seata下载地址:https://github.com/seata/seata/releases
进入官网不会下载,请参考如下截图:
1.下载Window版本后,打开如图所示
2.其中Context.txt配置如图
service.vgroupMapping.default_tx_group=default
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1/:3306/nacos-mysql?useUnicode=true
store.db.user=root
store.db.password=123456
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
3.然后进入seata-server1.4.2\conf目录中修改对应的参数
image.png
4.开始编辑file.conf文件
5.配置seata-server-1.4.2/conf/registry.conf
6.下载Seata对应的Mysql脚本:https://github.com/seata/seata/blob/develop/script/server/db/mysql.sql
下面还有Oracle数据库的脚本,也可以前往Github获得所有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`),
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);
7.如果是Oracle对应的脚本如下:
创建名称为seata的数据库,字符集utf8mb4、排序规则utf8mb4_general_ci
nacos的配置首先要修改连接的数据库,在oracle新建一个SEATA命名空间和用户,并插入三张表(global_table,branch_table,lock_table),脚本如下
-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE global_table
(
xid VARCHAR2(128) NOT NULL,
transaction_id NUMBER(19),
status NUMBER(3) NOT NULL,
application_id VARCHAR2(32),
transaction_service_group VARCHAR2(32),
transaction_name VARCHAR2(128),
timeout NUMBER(10),
begin_time NUMBER(19),
application_data VARCHAR2(2000),
gmt_create TIMESTAMP(0),
gmt_modified TIMESTAMP(0),
PRIMARY KEY (xid)
);
CREATE INDEX idx_gmt_modified_status ON global_table (gmt_modified, status);
CREATE INDEX idx_transaction_id ON global_table (transaction_id);
-- the table to store BranchSession data
CREATE TABLE branch_table
(
branch_id NUMBER(19) NOT NULL,
xid VARCHAR2(128) NOT NULL,
transaction_id NUMBER(19),
resource_group_id VARCHAR2(32),
resource_id VARCHAR2(256),
branch_type VARCHAR2(8),
status NUMBER(3),
client_id VARCHAR2(64),
application_data VARCHAR2(2000),
gmt_create TIMESTAMP(6),
gmt_modified TIMESTAMP(6),
PRIMARY KEY (branch_id)
);
CREATE INDEX idx_xid ON branch_table (xid);
-- the table to store lock data
CREATE TABLE lock_table
(
row_key VARCHAR2(128) NOT NULL,
xid VARCHAR2(96),
transaction_id NUMBER(19),
branch_id NUMBER(19) NOT NULL,
resource_id VARCHAR2(256),
table_name VARCHAR2(32),
pk VARCHAR2(36),
gmt_create TIMESTAMP(0),
gmt_modified TIMESTAMP(0),
PRIMARY KEY (row_key)
);
CREATE INDEX idx_branch_id ON lock_table (branch_id);
修改seata配置
store.db.dbType=oracle
# 这里是个坑OracleDriver并不存在在seata服务代码里
store.db.driverClassName=oracle.jdbc.OracleDriver
store.db.url=jdbc:oracle:thin:@192.168.1.135:1521:helowin
store.db.user=SEATA
store.db.password=SEATA
8.业务数据库中添加项目数据库undo_log(就是你应用平台的数据库)
和mysql一样,项目数据库也需要每个库都加入undo_log表,脚本如下
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE undo_log
(
id NUMBER(19) NOT NULL,
branch_id NUMBER(19) NOT NULL,
xid VARCHAR2(100) NOT NULL,
context VARCHAR2(128) NOT NULL,
rollback_info BLOB NOT NULL,
log_status NUMBER(10) NOT NULL,
log_created TIMESTAMP(0) NOT NULL,
log_modified TIMESTAMP(0) NOT NULL,
PRIMARY KEY (id),
CONSTRAINT ux_undo_log UNIQUE (xid, branch_id)
);
COMMENT ON TABLE undo_log IS 'AT transaction mode undo table';
-- Generate ID using sequence and trigger
CREATE SEQUENCE UNDO_LOG_SEQ START WITH 1 INCREMENT BY 1;
9.创建nacos-config.sh
内容从Github链接nacos-config.sh中复制粘贴即可
10.然后再来看一下Seata的官方文档
打开找到Nacos配置中心(Nacos是目前最主流的注册中心)
执行命令自动构建Nacos配置
11.启动Nacos创建一个命令空间如图
12.初始化脚本数据到nacos
在执行以下命令,将配置自动加载到Nacos中
sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 此为上面的Nacos的Namespace的ID -u nacos -w nacos
然后查看Nacos中是否有配置
13.下载的Nacos中脚本下载说明
14.直接访问在Github中获取Seata中所需的文件
点击 参考部署指南
到Github获取sql脚本/各个配置中心参数导入脚本,config.txt/server端数据库脚本
15.SpringBoot中添加配置
也可以参考官方文档http://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html
点击查看官方文档
com.alibaba.cloud
spring-cloud-alibaba-seata
2.2.0.RELEASE
io.seata
seata-spring-boot-starter
io.seata
seata-spring-boot-starter
1.4.0
druid
com.alibaba
yaml应用服务配置
seata: ## Seata分布式事务配置管理
enabled: true
enable-auto-data-source-proxy: true
# seata 事务组编号 用于TC集群名 # 必须和config.txt里面配置的属性一致
tx-service-group: default_tx_group
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
config:
# 必须写nacos,否则默认file
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
username: nacos
password: nacos
namespace: nacos的namespaced例如:65f556f2-1dc4-4b13-af44-6914f7f5bf73
service:
# 事务组对应的集群名称
vgroup-mapping:
default_tx_group: default
disable-global-transaction: false
client:
rm:
report-success-enable: false
15.如果以上都配置完毕,就启动Seata/应用服务
BUG问题
can not get cluster name in registry config
'service.vgroupMapping.account-service-fescar-service-group'
please make sure registry config correct