一材诽、概述
在微服務(wù)架構(gòu)下底挫,雖然我們會(huì)盡量避免分布式事務(wù),但是只要業(yè)務(wù)復(fù)雜的情況下這是一個(gè)繞不開的問題脸侥,如何保證業(yè)務(wù)數(shù)據(jù)一致性呢建邓?本文主要介紹同步場景下使用Seata的AT模式來解決一致性問題。
Seata
是阿里開源的一款開源的分布式事務(wù)解決方案睁枕,致力于提供高性能和簡單易用的分布式事務(wù)服務(wù)涝缝。Seata 將為用戶提供了 AT、TCC譬重、SAGA 和 XA 事務(wù)模式拒逮,為用戶打造一站式的分布式解決方案
二、Seata簡介
整體事務(wù)邏輯是基于 兩階段提交 的模型臀规,核心概念包括以下3個(gè)角色:
- TM:事務(wù)的發(fā)起者滩援。用來告訴 TC,全局事務(wù)的開始塔嬉,提交玩徊,回滾。
- RM:具體的事務(wù)資源谨究,每一個(gè) RM 都會(huì)作為一個(gè)分支事務(wù)注冊(cè)在 TC恩袱。
- TC:事務(wù)的協(xié)調(diào)者seata-server,用于接收我們的事務(wù)的注冊(cè)胶哲,提交和回滾畔塔。
根據(jù)兩階段行為模式的不同,我們將分支事務(wù)劃分為Automatic (Branch) Transaction Mode
和 Manual (Branch) Transaction Mode
2.1. AT模式
該模式適合的場景:
- 基于支持本地 ACID 事務(wù)的關(guān)系型數(shù)據(jù)庫鸯屿。
- Java 應(yīng)用澈吨,通過 JDBC 訪問數(shù)據(jù)庫。
- 一階段 prepare 行為:在本地事務(wù)中寄摆,一并提交業(yè)務(wù)數(shù)據(jù)更新和相應(yīng)回滾日志記錄谅辣。
- 二階段 commit 行為:馬上成功結(jié)束,自動(dòng) 異步批量清理回滾日志婶恼。
- 二階段 rollback 行為:通過回滾日志桑阶,自動(dòng) 生成補(bǔ)償操作柏副,完成數(shù)據(jù)回滾。
一個(gè)典型的分布式事務(wù)過程:
- TM 向 TC 申請(qǐng)開啟一個(gè)全局事務(wù)蚣录,全局事務(wù)創(chuàng)建成功并生成一個(gè)全局唯一的 XID搓扯。
- XID 在微服務(wù)調(diào)用鏈路的上下文中傳播。
- RM 向 TC 注冊(cè)分支事務(wù)包归,將其納入 XID 對(duì)應(yīng)全局事務(wù)的管轄。
- TM 向 TC 發(fā)起針對(duì) XID 的全局提交或回滾決議铅歼。
- TC 調(diào)度 XID 下管轄的全部分支事務(wù)完成提交或回滾請(qǐng)求公壤。
2.2. MT模式
該模式邏輯類似TCC,需要 自定義實(shí)現(xiàn) prepare椎椰、commit和rollback的邏輯厦幅,適合 非關(guān)系型數(shù)據(jù)庫 的場景
TCC(MT) 模式,不依賴于底層數(shù)據(jù)資源的事務(wù)支持:
- 一階段 prepare 行為:調(diào)用 自定義 的 prepare 邏輯慨飘。
- 二階段 commit 行為:調(diào)用 自定義 的 commit 邏輯确憨。
- 二階段 rollback 行為:調(diào)用 自定義 的 rollback 邏輯。
所謂 TCC 模式瓤的,是指支持把 自定義 的分支事務(wù)納入到全局事務(wù)的管理中休弃。
三、示例版本說明
- Seata 1.3.0
- Nacos 1.4.0
- SpringBoot 2.2.10.RELEASE
- SpringCloud Hoxton.SR8
- SpringCloudAlibaba 2.2.3.RELEASE
啟動(dòng)Nacos
- 下載地址
- 創(chuàng)建數(shù)據(jù)庫
nacos-config
sql腳本文件在nacos-server-1.4.0\nacos\conf
目錄下nacos-mysql.sql
/******************************************/
/* 數(shù)據(jù)庫全名 = nacos_config */
/* 表名稱 = config_info */
/******************************************/
CREATE TABLE `config_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) DEFAULT NULL,
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時(shí)間',
`src_user` text COMMENT 'source user',
`src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租戶字段',
`c_desc` varchar(256) DEFAULT NULL,
`c_use` varchar(64) DEFAULT NULL,
`effect` varchar(64) DEFAULT NULL,
`type` varchar(64) DEFAULT NULL,
`c_schema` text,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
/******************************************/
/* 數(shù)據(jù)庫全名 = nacos_config */
/* 表名稱 = config_info_aggr */
/******************************************/
CREATE TABLE `config_info_aggr` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) NOT NULL COMMENT 'group_id',
`datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
`content` longtext NOT NULL COMMENT '內(nèi)容',
`gmt_modified` datetime NOT NULL COMMENT '修改時(shí)間',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租戶字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租戶字段';
/******************************************/
/* 數(shù)據(jù)庫全名 = nacos_config */
/* 表名稱 = config_info_beta */
/******************************************/
CREATE TABLE `config_info_beta` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時(shí)間',
`src_user` text COMMENT 'source user',
`src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租戶字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
/******************************************/
/* 數(shù)據(jù)庫全名 = nacos_config */
/* 表名稱 = config_info_tag */
/******************************************/
CREATE TABLE `config_info_tag` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時(shí)間',
`src_user` text COMMENT 'source user',
`src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';
/******************************************/
/* 數(shù)據(jù)庫全名 = nacos_config */
/* 表名稱 = config_tags_relation */
/******************************************/
CREATE TABLE `config_tags_relation` (
`id` bigint(20) NOT NULL COMMENT 'id',
`tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
`tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`nid` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`nid`),
UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';
/******************************************/
/* 數(shù)據(jù)庫全名 = nacos_config */
/* 表名稱 = group_capacity */
/******************************************/
CREATE TABLE `group_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID圈膏,空字符表示整個(gè)集群',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配額塔猾,0表示使用默認(rèn)值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '單個(gè)配置大小上限,單位為字節(jié)稽坤,0表示使用默認(rèn)值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大個(gè)數(shù)丈甸,,0表示使用默認(rèn)值',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '單個(gè)聚合數(shù)據(jù)的子配置大小上限尿褪,單位為字節(jié)睦擂,0表示使用默認(rèn)值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大變更歷史數(shù)量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時(shí)間',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';
/******************************************/
/* 數(shù)據(jù)庫全名 = nacos_config */
/* 表名稱 = his_config_info */
/******************************************/
CREATE TABLE `his_config_info` (
`id` bigint(64) unsigned NOT NULL,
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`data_id` varchar(255) NOT NULL,
`group_id` varchar(128) NOT NULL,
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL,
`md5` varchar(32) DEFAULT NULL,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`src_user` text,
`src_ip` varchar(20) DEFAULT NULL,
`op_type` char(10) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租戶字段',
PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`),
KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租戶改造';
/******************************************/
/* 數(shù)據(jù)庫全名 = nacos_config */
/* 表名稱 = tenant_capacity */
/******************************************/
CREATE TABLE `tenant_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配額杖玲,0表示使用默認(rèn)值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '單個(gè)配置大小上限顿仇,單位為字節(jié),0表示使用默認(rèn)值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大個(gè)數(shù)',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '單個(gè)聚合數(shù)據(jù)的子配置大小上限摆马,單位為字節(jié)夺欲,0表示使用默認(rèn)值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大變更歷史數(shù)量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時(shí)間',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租戶容量信息表';
CREATE TABLE `tenant_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`kp` varchar(128) NOT NULL COMMENT 'kp',
`tenant_id` varchar(128) default '' COMMENT 'tenant_id',
`tenant_name` varchar(128) default '' COMMENT 'tenant_name',
`tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
`create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
`gmt_create` bigint(20) NOT NULL COMMENT '創(chuàng)建時(shí)間',
`gmt_modified` bigint(20) NOT NULL COMMENT '修改時(shí)間',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
CREATE TABLE `users` (
`username` varchar(50) NOT NULL PRIMARY KEY,
`password` varchar(500) NOT NULL,
`enabled` boolean NOT NULL
);
CREATE TABLE `roles` (
`username` varchar(50) NOT NULL,
`role` varchar(50) NOT NULL,
UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);
CREATE TABLE `permissions` (
`role` varchar(50) NOT NULL,
`resource` varchar(255) NOT NULL,
`action` varchar(8) NOT NULL,
UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
- 修改
/conf/application.properties
配置文件中的數(shù)據(jù)源信息。其他配置可以參考Nacos文檔
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_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=root
- 啟動(dòng)Nacos
單機(jī)模式
startup.cmd -m standalone
啟動(dòng)成功后訪問http://127.0.0.1:8848/nacos
用戶名今膊、密碼均為nacos
啟動(dòng)Seata-Server
下載Seata
初始化數(shù)據(jù)庫
- 創(chuàng)建數(shù)據(jù)庫
seata_config
- 初始化腳本如下些阅,在1.0及以下版本中提供(大坑)
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for branch_table
-- ----------------------------
DROP TABLE IF EXISTS `branch_table`;
CREATE TABLE `branch_table` (
`branch_id` bigint(20) NOT NULL,
`xid` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`transaction_id` bigint(20) NULL DEFAULT NULL,
`resource_group_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`resource_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`branch_type` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`status` tinyint(4) NULL DEFAULT NULL,
`client_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`application_data` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`gmt_create` datetime(6) NULL DEFAULT NULL,
`gmt_modified` datetime(6) NULL DEFAULT NULL,
PRIMARY KEY (`branch_id`) USING BTREE,
INDEX `idx_xid`(`xid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of branch_table
-- ----------------------------
-- ----------------------------
-- Table structure for global_table
-- ----------------------------
DROP TABLE IF EXISTS `global_table`;
CREATE TABLE `global_table` (
`xid` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`transaction_id` bigint(20) NULL DEFAULT NULL,
`status` tinyint(4) NOT NULL,
`application_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`transaction_service_group` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`transaction_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`timeout` int(11) NULL DEFAULT NULL,
`begin_time` bigint(20) NULL DEFAULT NULL,
`application_data` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`gmt_create` datetime(0) NULL DEFAULT NULL,
`gmt_modified` datetime(0) NULL DEFAULT NULL,
PRIMARY KEY (`xid`) USING BTREE,
INDEX `idx_gmt_modified_status`(`gmt_modified`, `status`) USING BTREE,
INDEX `idx_transaction_id`(`transaction_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of global_table
-- ----------------------------
-- ----------------------------
-- Table structure for lock_table
-- ----------------------------
DROP TABLE IF EXISTS `lock_table`;
CREATE TABLE `lock_table` (
`row_key` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`xid` varchar(96) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`transaction_id` bigint(20) NULL DEFAULT NULL,
`branch_id` bigint(20) NOT NULL,
`resource_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`table_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`pk` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`gmt_create` datetime(0) NULL DEFAULT NULL,
`gmt_modified` datetime(0) NULL DEFAULT NULL,
PRIMARY KEY (`row_key`) USING BTREE,
INDEX `idx_branch_id`(`branch_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of lock_table
-- ----------------------------
SET FOREIGN_KEY_CHECKS = 1;
同步配置至Nacos
在seata-1.3.0源碼中seata\script\config-center\config.txt
復(fù)制到解壓后的seata包中
并修改如下配置
service.vgroupMapping.my_test_tx_group=default
store.mode=db
store.db.url=jdbc:mysql://127.0.0.1:3306/seata_config?useUnicode=true
store.db.user=root
store.db.password=root
其中my_test_tx_group是事物分組名稱,可以隨意修改但要注意必須與工程中的配置相同
復(fù)制seata-1.3.0源碼目錄seata\script\config-center\nacos\nacos-config.sh
文件至seata
解壓包conf\script
目錄下斑唬,并運(yùn)行 sh nacos-config.sh 127.0.0.1
注意:這里因?yàn)槭莝h腳本市埋,可以使用cmder或git的bash命令窗口,并且腳本文件必須在
config.txt
文件的子文件夾中
成功后命令行輸出所有同步至nacos中的配置信息黎泣,并輸出init nacos config finished, please start seata-server
表示同步配置成功
打開配置中心也可以看到配置信息
- 運(yùn)行
seata-server.bat | seata-server.sh
啟動(dòng)seata 觀察控制臺(tái)監(jiān)聽在8091
端口
SpringCloudAlibaba集成Seata
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
參考官網(wǎng)實(shí)例案例和demo,版本差異稍作修改
- 初始化業(yè)務(wù)數(shù)據(jù)庫
seata_demo
缤谎,在seata官方示例demo中有提供sql腳本
-- 創(chuàng)建 order庫抒倚、業(yè)務(wù)表、undo_log表
create database seata_order;
use seata_order;
DROP TABLE IF EXISTS `order_tbl`;
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 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,
`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,
`ext` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8;
-- 創(chuàng)建 storage庫坷澡、業(yè)務(wù)表托呕、undo_log表
create database seata_storage;
use seata_storage;
DROP TABLE IF EXISTS `storage_tbl`;
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`)
) ENGINE=InnoDB 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,
`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,
`ext` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8;
-- 初始化庫存模擬數(shù)據(jù)
INSERT INTO seata_storage.storage_tbl (id, commodity_code, count) VALUES (1, 'product-1', 9999999);
INSERT INTO seata_storage.storage_tbl (id, commodity_code, count) VALUES (2, 'product-2', 0);
-
application.yml
配置如下
seata:
tx-service-group: my_test_tx_group
config:
type: nacos
nacos:
serverAddr: ${spring.cloud.nacos.server-addr}
group: SEATA_GROUP
username: nacos
password: nacos
registry:
type: nacos
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
group: SEATA_GROUP
username: nacos
password: nacos
注意:配置中
tx-service-group
必須和config.txt
中的vgroupMapping
配置一致(已同步至Nacos配置中心)
- 分別運(yùn)行
business-service
、storage-service
频敛、order-service
项郊、account-service
啟動(dòng)成功后調(diào)用下單成功和異常接口
觀察控制臺(tái)日志可以看到各服務(wù)的事務(wù)id如下
biz: 87904197444374528 #bisness-service(TM)向TC申請(qǐng)的全局事物ID XID
storage: 87904197503094784 #storage-service 分支事物id
order : 87904197620535297 #order-service 分支事物id
account: 87904197729587201 #account-service 分支事物id
當(dāng)出現(xiàn)異常時(shí)TC會(huì)通知所有RM回滾事務(wù)
PhaseTwo_Rollbacked