Spring Cloud 使用 Seata 实现分布式事务,Nacos 作为 Seata 配置中心
使用 Seata 作为分布式事务组件,配置中心和注册中心使用 Nacos,使用 MySQL 数据库和 MyBatis,同时使用 Nacos 作为 Seata 的配置中心
至于对Nacos和Seata的介绍,请移步GitHub官网:
Nacos:https://nacos.io/zh-cn/docs/quick-start.html
Seata:https://github.com/seata/seata/wiki/Home_Chinese
Nacos Server下载地址:https://github.com/alibaba/nacos/releases
Seata Server下载地址:https://github.com/seata/seata/releases
文章中的源码在GitHub
环境准备
创建数据库及表(在官方demo中的all_in_one.sql)
- 要求:带有InnoDB引擎的MySQL。
注意:实际上,示例用例中的3个服务应该有3个数据库。但是,我们只需创建一个数据库并配置3个数据源即可。
- 业务表
create schema db_account;
use db_account;
CREATE TABLE `account_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`money` int(11) DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO account_tbl (id, user_id, money) VALUES (1, '1001', 10000);
INSERT INTO account_tbl (id, user_id, money) VALUES (2, '1002', 10000);
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
create schema db_order;
use db_order;
CREATE TABLE `order_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`commodity_code` varchar(255) DEFAULT NULL,
`count` int(11) DEFAULT '0',
`money` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
create schema db_storage;
use db_storage;
CREATE TABLE `storage_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`commodity_code` varchar(255) DEFAULT NULL,
`count` int(11) DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `commodity_code` (`commodity_code`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO storage_tbl (id, commodity_code, count) VALUES (1, '2001', 1000);
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
启动 Nacos
这里的 Nacos 配置使用的是本地启动的,nacos.config 的 Group, namespace 都是默认的,如果需要可以修改成自己对应的,可以参考官方文档:https://nacos.io/zh-cn/docs/quick-start.html
sh startup.sh -m standalone
启动 Seata Server
- 在 Seata Release 下载最新版的 Seata Server 并解压得到如下目录:
. ├──bin ├──conf ├──file_store └──lib
- 修改
conf/registry.conf
配置,将 type 改为nacos
registry {
type = "nacos"
nacos {
serverAddr = "localhost"
namespace = "public"
cluster = "default"
}
}
config {
type = "nacos"
nacos {
serverAddr = "localhost"
namespace = "public"
cluster = "default"
}
}
- 修改
conf/nacos-config.txt
配置
修改 service.vgroup_mapping
为自己应用对应的名称;如果有多个服务,添加相应的配置(service.vgroup_mapping后面的值要与spring.cloud.alibaba.seata.tx-service-group对应的值匹配)如:
service.vgroup_mapping.my_test_tx_group=default
//改为
service.vgroup_mapping.storage-service-fescar-service-group=default
service.vgroup_mapping.order-service-fescar-service-group=default
service.vgroup_mapping.business-service-fescar-service-group=default
service.vgroup_mapping.account-service-fescar-service-group=default
也可以在 Nacos 配置页面添加,data-id 为 service.vgroup_mapping.${YOUR_SERVICE_NAME}-fescar-service-group
, group 为 SEATA_GROUP
, 如果不添加该配置,启动后会提示no available server to connect
注意配置文件末尾有空行,需要删除,否则会提示失败,尽管实际上是成功的
- 将 Seata 配置添加到 Nacos 中
cd conf
sh nacos-config.sh localhost
成功后会提示
init nacos config finished, please start seata-server
在 Nacos 管理页面应该可以看到有 47 个 Group 为SEATA_GROUP
的配置
- 启动 Seata Server
cd ..
sh ./bin/seata-server.sh 8091 file
启动后在 Nacos 的服务列表下面可以看到一个名为serverAddr
的服务
用例
参考官网中用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:
- 存储服务:扣除给定商品的存储数量。
- 订单服务:根据购买请求创建订单。
- 帐户服务:借记用户帐户的余额。
请求逻辑
分别启动:
ExampleBusinessApplication
ExampleAccountApplication
ExampleOrderApplication
ExampleStorageApplication
其中ExampleBusinessApplication服务中暴露了两个主要测试接口
http://127.0.0.1:8084/purchase/commit接口是可以正常执行完成的方法
http://127.0.0.1:8084/purchase/rollback接口是会发生异常并正常回滚的方法
需要修改的文件:
1、各个服务中的application.properties的spring.cloud.alibaba.seata.tx-service-group
2、各个服务中的registry.conf的type
3、seata-server中的conf/nacos-config.txt的
service.vgroup_mapping
文章参考:
https://github.com/helloworlde/spring-cloud-alibaba-component/tree/master/cloud-seata-nacos