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