本文都是在项目部署都是基于windos
1 Seata
1.1 Seata 模式简介
AT模式
如果不熟悉(就是我)分布式相关解决模式的相关知识,可以看一个b站的视频,从76P开始讲Seata的,有助于更加了解Seata的机制。
1.2 Seata配置
①下载 + 解压(推荐一直都在用的BandZip)
②初始化数据库(创建名为seata的数据库并运行下面的sql文件,创建seata运行所需要的三张表)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| -- -------------------------------- 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_gmt_modified_status` (`gmt_modified`, `status`), KEY `idx_transaction_id` (`transaction_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;
-- 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 = utf8;
-- the table to store lock data CREATE TABLE IF NOT EXISTS `lock_table` ( `row_key` VARCHAR(128) NOT NULL, `xid` VARCHAR(96), `transaction_id` BIGINT, `branch_id` BIGINT NOT NULL, `resource_id` VARCHAR(256), `table_name` VARCHAR(32), `pk` VARCHAR(36), `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`row_key`), KEY `idx_branch_id` (`branch_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;
|
②修改配置文件
进入seata\config
目录,如果要使用集群模式,需要修改:file.config
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| store { ## 修改模式,改为db mode = "db"
file { dir = "sessionStore" maxBranchSessionSize = 16384 maxGlobalSessionSize = 512 fileWriteBufferCacheSize = 16384 sessionReloadReadSize = 100 flushDiskMode = async } db { datasource = "druid" dbType = "mysql" driverClassName = "com.mysql.jdbc.Driver" ## 修改数据库连接(连接到第一部配置的seata数据库)的配置,url、user、password url = "jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true" user = "root" password = "Qwer;t592665" minConn = 5 maxConn = 30 globalTable = "global_table" branchTable = "branch_table" lockTable = "lock_table" queryLimit = 100 maxWait = 5000 } }
|
③设置nacos为注册中心
进入seata\config
目录,修改:registry.config
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| registry { #注册为nacos type = "nacos"
nacos { application = "seata-server" serverAddr = "localhost:8848" namespace = "public" cluster = "default" username = "" password = "" } file { name = "file.conf" } }
config { ##修改为nacos配置 type = "nacos"
nacos { serverAddr = "localhost" namespace = "public" group = "SEATA_GROUP" username = "" password = "" } file { name = "file.conf" } }
|
④启动Seata
1.在RELEASE页面下载相应版本并解压
2.直接启动
在 Linux/Mac 下
1
| $ sh ./bin/seata-server.sh
|
在 Windows 下
接下来我们部署Nacos作为Seata的配置中心
2 Nacos
2.1Nacos部署
①在nacos下载页面中下载,我下载时最新版本为1.3.0
②创建数据库nacos以及相应的表(在conf
目录下有sql文件)
1 2 3 4 5 6 7 8 9 10 11 12 13
| CREATE TABLE seata_order.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;
|
③配置数据库连接信息
在nacos\conf目录下找到application.properties
配置文件,增加MySQL配置:
1 2 3 4 5 6 7 8 9 10 11 12
| #*************** Config Module Related Configurations ***************# ### If user MySQL as datasource: spring.datasource.platform=mysql
### Count of DB: db.num=1
### Connect URL of DB: db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC db.user=root db.password=******
|
③启动Nacos服务
windows就是startup.cmd(linux就是startup.sh)。
④打开 http://127.0.0.1:8848/nacos 地址,使用默认的用户「nacos/nacos」进行登陆。
这样我们就算部署成功了。
3 SpringBoot相关配置
可以参照芋道的内容。
①设置分支事务回滚表undo_log
。
项目中每个数据库都要设置相应的undo_log
表用于分支事务的回滚。
1 2 3 4 5 6 7 8 9 10 11 12 13
| CREATE TABLE seata_order.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;
|
②引入依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <dependency> <groupId>io.seata</group Id> <artifactId>seata-spring-boot-starter</artifactId> <version>1.2.0</version> </dependency>
<dependency> <groupId>com.alibaba.boot</groupId> <artifactId>nacos-config-spring-boot-starter</artifactId> <version>0.2.4</version> </dependency>
<dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.0.0</version> </dependency>
|
③配置文件
修改application.yaml
,没有就创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| server: port: 8081 servlet: context-path: /parking
spring: application: name: parking
datasource: dynamic: primary: all-ds datasource: all-ds: url: jdbc:mysql://127.0.0.1:3306/parking_lot?useSSL=false&useUnicode=true&characterEncoding=UTF-8 driver-class-name: com.mysql.jdbc.Driver username: root password: Qwer;t592665 swpu-ds: url: jdbc:mysql://127.0.0.1:3306/parking_lot_swpu?useSSL=false&useUnicode=true&characterEncoding=UTF-8 driver-class-name: com.mysql.jdbc.Driver username: root password: Qwer;t592665 seata: true
seata: application-id: ${spring.application.name} tx-service-group: ${spring.application.name}-group service: vgroup-mapping: parking-group: default grouplist: default: 127.0.0.1:8091
|
④项目实例可以参考芋道的文章。
⑤总结一下我遇到的问题:
1:no available service ‘null’ found, please make sure registry config correct
因为我开始参考的是别人的项目,有些细节没弄清楚,看了一下github大家的issue,突然想到seata的事务组名称(也就是vgroup mapping下面第一个配置项目的key)这里必须设置为:你的项目名称
+-group
,我这里就是parking-group。
2:RM register failed
主要原因是我的GlobalTransaction没有管理到 到Transactional,导致这事务之间没有联系一起