Spring Cloud Nacos整合 Seata 实现分布式事务
1、Seata 介绍
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
2、软件版本
软件 |
版本 |
地址 |
JDK |
1.8.0_271 |
Java Downloads | Oracle |
Spring Boot |
2.5.6 |
Spring Boot |
Spring Cloud |
2020.0.4 |
Spring Cloud |
Nacos |
2.0.3 |
Releases · alibaba/nacos · GitHub |
Seata |
1.4.2 |
https://github.com/seata/seata/releases |
3、环境搭建
3.1、安装Nacos
3.1.1、下载nacos
下载nacos-2.0.3.zip
地址:Releases · alibaba/nacos · GitHub
3.1.2、启动nacos服务
解压nacos-2.0.3.zip,进入nacos安装目录bin目录下,执行startup.sh/startup.cmd脚本。
CentOS 或 Mac 启动Nacos
sh startup.sh -m standalone
windows 启动Nacos
startup.cmd -m standalone
浏览器输入:http://127.0.0.1:8848/nacos/index.html 进行访问,账号/密码:nacos/nacos 进行登录。
3.2、安装Seata
3.2.1、下载seata-server
下载seata-server-1.4.2.zip
地址:https://github.com/seata/seata/releases
3.2.2、安装seata-server
解压seata-server-1.4.2.zip
3.2.3、 seata数据库配置
创建seata数据库,并创建seata服务需要的表:
新建seata数据库,将 seata 服务端需要的表初始化到数据库中
seata-server 需要的数据库脚本:
https://github.com/seata/seata/tree/v1.4.2/script/server/db
seata-client 需要的数据库脚本:
https://github.com/seata/seata/tree/v1.4.2/script/client/at/db
Seata AT 模式,客户端只需要 undo_log表,下面要新建业务表t_account、t_order、t_storage 三张业务表,如果三张表放到一个数据库里面,只需要新建一个 undo_log 表,如果将三张表拆分到三个数据库里面,则每个数据库都需要创建 undo_log 表,脚本文件地址
3.2.4、配置seata-server
下载seata-server需要上传nacos相关脚本,脚本地址
https://github.com/seata/seata/tree/develop/script/config-center
其中config.txt 是上传nacos配置的内容,nacos目录下的nacos-config.sh是将config.txt推送到nacos的脚本。
把confi.txt 复制到seata根目录,nacos里面的脚本复制到seata/conf目录,如下图所示:
修改seata-server-1.4.2/config.txt,目前需要推送到nacos的只有下面这些,其他的可以暂时忽略。需要配置的内容如下:
service.vgroupMapping.my_test_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/seata?useUnicode=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai
store.db.user=root
store.db.password=root
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
其中 seata 是seata 服务端使用的数据库
使用conf目录下的nacos-config.sh,将txt文件里面的内容推送到nacos上
sh nacos-config.sh -h localhost -p 8848 -u nacos -w nacos
备注:windows平台可以使用Git 运行nacos-config.sh脚本
nacos-config.sh命令的参数如下:
sh nacos-config.sh -h localhost -p 8848 -u username -w password
Parameter Description:
-h: host, the default value is localhost.
-p: port, the default value is 8848.
-g: Configure grouping, the default value is 'SEATA_GROUP'.
-t: Tenant information, corresponding to the namespace ID field of Nacos, the default value is ''.
-u: username, nacos 1.2.0+ on permission control, the default value is ''.
-w: password, nacos 1.2.0+ on permission control, the default value is ''.
执行成功后,打开nacos控制台
seata-server-1.4.2/conf目录里面,file.conf和registry.conf,由于使用的是nacos注册中心,file.conf里面相关的配置已经推送到了nacos,所以只需要修改registry.conf
registry.conf
registry {# file 、nacos 、eureka、redis、zk、consul、etcd3、sofatype = "nacos"nacos {application = "seata-server"serverAddr = "127.0.0.1"group = "SEATA_GROUP"namespace = ""cluster = "default"username = ""password = ""}
}config {# file、nacos 、apollo、zk、consul、etcd3type = "nacos"nacos {serverAddr = "127.0.0.1"namespace = ""group = "SEATA_GROUP"username = "nacos"password = "nacos"dataId = "seataServer.properties"}
}
3.2.5、启动Seata服务
执行 seata-server-1.4.2\bin 目录下的 seata-server.bat/seata-server.sh 启动seata服务
打开nacos控制台,此时seata已经成功注册到nacos注册中心
4、项目架构
4.1、项目说明
用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:
- 采购服务(business-service):购买商品的业务逻辑,也是事务的发起者。
- 仓储服务(storage-service):对给定的商品扣除仓储数量。
- 订单服务(order-service):根据采购需求创建订单。
- 帐户服务(account-service):从用户帐户中扣除余额。
4.2、项目架构
5、项目搭建
5.1、项目结构
5.2、表结构初始化
初始化订单、库存、账户三张表
-- ----------------------------
-- Table structure for t_account
-- ----------------------------
DROP TABLE IF EXISTS `t_account`;
CREATE TABLE `t_account` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`user_id` bigint(20) NOT NULL DEFAULT 0,`money` bigint(20) NOT NULL DEFAULT 0,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4;-- ----------------------------
-- Records of t_account
-- ----------------------------
INSERT INTO `t_account` VALUES (1, 10001, 10000);-- ----------------------------
-- Table structure for t_order
-- ----------------------------
DROP TABLE IF EXISTS `t_order`;
CREATE TABLE `t_order` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`user_id` bigint(20) NOT NULL DEFAULT 0,`commodity_code` varchar(20) CHARACTER SET utf8mb4 NOT NULL DEFAULT '',`count` int(10) NOT NULL DEFAULT 0,`money` bigint(20) NOT NULL DEFAULT 0,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4;-- ----------------------------
-- Records of t_order
-- ------------------------------ ----------------------------
-- Table structure for t_storage
-- ----------------------------
DROP TABLE IF EXISTS `t_storage`;
CREATE TABLE `t_storage` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`commodity_code` varchar(50) CHARACTER SET utf8mb4 NOT NULL DEFAULT '',`commodity_name` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '',`count` int(11) NOT NULL DEFAULT 0,`price` bigint(20) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `commodity_code`(`commodity_code`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4;-- ----------------------------
-- Records of t_storage
-- ----------------------------
INSERT INTO `t_storage` VALUES (1, '10001', '苹果手机', 100, 100);
5.3、服务搭建
5.3.1、pom依赖
order-service、storage-service、account-service三个服务的pom.xml的依赖一样,business-service服务不需要连接数据库,所以不需要引用mybatis-plus-boot-starter和mysql-connector-java
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId>
</dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>
5.3.2、application.yml
order-service、storage-service、account-service三个服务的application.yml基本一致,其中需要修改的有以下几个地方:
server.portspring.application.namemybatis-plus.type-aliases-packageseata.application-id
business-service服务不需要连接数据库,所以不用配置datasource和mybatis-plus节点
server:port: 9001spring:application:name: order-servicecloud:nacos:discovery:username: nacospassword: nacos# Nacos 服务发现与注册配置server-addr: 127.0.0.1:8848# 注册到 nacos 的指定 namespace,默认为 publicnamespace: publicdatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/seata?characterEncoding=utf-8username: rootpassword: root
mybatis-plus:global-config:banner: falseconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志map-underscore-to-camel-case: true # 开启驼峰type-aliases-package: com.seata.order.entity #定义所有操作类的别名所在包mapper-locations: classpath:mapper/*Mapper.xml# seata config
seata:enabled: trueapplication-id: order-servicetx-service-group: my_test_tx_group # 事务群组(可以每个应用单独取名,也可以使用相同名字,独立起名需要配置nacos)registry:type: nacosnacos:server-addr: 127.0.0.1:8848namespace:cluster: defaultconfig:type: nacosnacos:namespace:server-addr: 127.0.0.1:8848
5.3.3、seata配置说明(这一步不用配置,只是说明一下)
registry.conf中内容已经配置到application.yml中,因此不需要引用registry.conf文件
如果不想正application.yml中配置seata相关内容,只需要将seata相关的脚本拷贝到项目resource目录下
文件地址https://github.com/seata/seata/tree/v1.4.2/script/client/conf
registry {# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa、customtype = "nacos"nacos {application = "seata-server"serverAddr = "127.0.0.1:8848"group = "SEATA_GROUP"namespace = ""username = ""password = ""}
}config {# file、nacos 、apollo、zk、consul、etcd3、springCloudConfig、customtype = "nacos"nacos {serverAddr = "127.0.0.1:8848"namespace = ""group = "SEATA_GROUP"username = ""password = ""dataId = "seata.properties"}
}
5.3.4、仓储服务
/*** 扣减库存*/int deductStorage(String commodityCode, int count);/*** 扣减库存** @param commodityCode 商品编码* @param count 数量* @return*/@Override@Transactional(rollbackFor = Exception.class)public int deductStorage(String commodityCode, int count) {log.info("[库存服务]>------>扣减库存开始");storageMapper.deductStorage(commodityCode, count);log.info("[库存服务]>------>扣减库存结束");return count;}
5.3.5、订单服务
创建订单服务接口:
/*** 创建订单*/Long createOrder(Long userId, String commodityCode, int count);
创建订单服务实现:
/*** 创建订单** @param userId* @param commodityCode* @param count* @return*/@Overridepublic Long createOrder(Long userId, String commodityCode, int count) {log.info("[订单服务]>------>创建订单开始");//扣减账户余额Long price = storageService.selectPrice(commodityCode);Long money = price * count;// 创建订单Order order = new Order();order.setUserId(userId);order.setCommodityCode(commodityCode);order.setMoney(money);order.setCount(count);orderMapper.insert(order);// 扣减账户log.info("[订单服务]>------>扣减账户开始");accountService.deductAccount(order.getUserId(), money);log.info("[订单服务]>------>扣减账户结束");log.info("[订单服务]>------>创建订单结束");return order.getId();}
5.3.6、帐户服务
/*** 扣减账户*/Long deductAccount(Long userId, Long money);
/*** 扣减账户* @param userId* @param money* @return*/@Overridepublic Long deductAccount(Long userId, Long money) {log.info("[账户服务]>------>扣减账户开始");if (10000 == userId) {throw new RuntimeException("[库存服务]>------>扣减库存异常");}accountMapper.deductAccount(userId, money);log.info("[账户服务]>------>扣减账户失败");return money;}
5.3.7、采购业务逻辑
采购业务逻辑,@GlobalTransactional 注解表示开启全局事务
/*** 扣减库存-》创建订单** @param userId 用户Id* @param commodityCode 商品编码* @param count 数量*/@Override@GlobalTransactional(timeoutMills = 10000, name = "spring-cloud-seata", rollbackFor = Exception.class)public Long purchase(Long userId, String commodityCode, int count) {log.info("开始全局事务,XID = " + RootContext.getXID());log.info("[采购服务]>------>扣减库存开始");storageService.deductStorage(commodityCode, count);log.info("[采购服务]>------>扣减库存结束");log.info("[采购服务]>------>创建订单开始");Long orderId = orderService.createOrder(userId, commodityCode, count);log.info("[采购服务]>------>创建订单结束");return orderId;}
5.3.8、查看服务启动情况
5.3 分布式事务测试
5.3.1、正常业务逻辑测试
postman测试:
请求地址:http://localhost:9000/business/purchase?userId=10001&commodityCode=10001&count=1
数据库中:订单表已经有一条数据,库存表商品库存数量减1
5.3.1、异常业务逻辑测试
项目完整地址:
https://github.com/jeespring/spring-cloud-seata
Spring Cloud Nacos整合 Seata 实现分布式事务相关推荐
- Spring Cloud Eureka整合 Seata 实现分布式事务
一.Seata 介绍 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的 ...
- Spring Cloud 整合 seata 实现分布式事务极简入门
Spring Cloud 整合 seata 实现分布式事务极简入门 seata Spring Cloud 整合 seata 实现分布式事务极简入门 1. 概述 2. 部署nacos 3. 部署seat ...
- springCloud整合seata实现分布式事务
seata简介 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式 ...
- Spring Cloud Alibaba系列四:集成 seata 实现分布式事务
文章目录 Spring Cloud Alibaba系列四:集成 seata 实现分布式事务 前言 Seata 是什么? Seata 术语 安装 seata 1.创建 seata 数据库,并添加对应的表 ...
- Spring Boot之基于Dubbo和Seata的分布式事务解决方案
转载自 Spring Boot之基于Dubbo和Seata的分布式事务解决方案 1. 分布式事务初探 一般来说,目前市面上的数据库都支持本地事务,也就是在你的应用程序中,在一个数据库连接下的操作,可以 ...
- 实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!
今天这篇文章介绍一下Spring Cloud Gateway整合OAuth2.0实现认证授权,涉及到的知识点有点多,有不清楚的可以看下陈某的往期文章. 文章目录如下: 微服务认证方案 微服务认证方案目 ...
- Spring Cloud Gateway整合Nacos实现服务路由及集群负载均衡
目录 一.序言 二.代码示例 1.父工程spring-cloud-gateway-learning 2.子工程spring-cloud-api-gateway (1) pom.xml (2) 配置文件 ...
- Spring Cloud Gateway 整合 knife4j 聚合接口文档
当系统中微服务数量越来越多时,如果任由这些服务散落在各处,那么最终管理每个项目的接口文档将是一件十分麻烦的事情,单是记住所有微服务的接口文档访问地址就是一件苦差事了.当如果能够将所有微服务项目的接口文 ...
- 使用Seata解决分布式事务以及Seata的安装、配置和使用
目录 事务的介绍 什么是本地事务? 分布式事务 分布式事务解决方案之seata Seata介绍 Seata是什么 Seata的分布式事务解决方案 Seata的核心组件 AT模式的工作流程 一阶段 二阶 ...
最新文章
- 苹果运行内存比较_决定手机流畅度到底是看CPU还是运行内存,你知道么?
- runtime error: invalid memory address or nil pointer dereference
- Android 插件化总结
- Shell下的环境变量
- [Vue源码分析] 模板的编译
- docker 发布tomcat项目_在docker中部署tomcat并且部署java应用程序的步骤详解
- CF938G Shortest Path Queries
- Sword pcre库函数学习三
- 学习OpenCV时 ,添加:#includeopencv2/core/core.hpp等头文件出现无法编译的错误
- HDU2544 最短路【Dijkstra算法】
- IPSEC 002 ---- Internet危机四伏,IPSec闪亮登场
- 【步骤详解】畅捷通T+Cloud无代码集成钉钉群机器人示例
- Java file.encoding
- XSS靶场练习 https://xss.haozi.me
- Log4J按照不同包名输出日志
- “智慧路灯”、“一杆多用”、“智慧灯杆”将成为新型智慧城市建设的重要决策部署
- 2021年焊工(初级)考试资料及焊工(初级)新版试题
- 致远OA自定义函数--正则表达式匹配校验
- 操作系统第七、八章习题
- 大数据在医疗领域应用有哪些挑战?
热门文章
- python报错No module named XXX解决方法
- ESP32-S2上使用SPI接口芯片DM9051NP转以太网的无线物联网网关开发指导
- 面向对象编程(OOP)
- 助眠好物推荐,帮助睡眠最好的办法
- thrift的使用介绍
- 多媒体计算机是指安装了什么部件的,多媒体计算机是指安装了什么的计算机
- java字符下落,重力球,加速下落减速上弹,重力下落,这段代码是看到网上一个关...
- caffe刚开始训练准确率很高,经过几次训练就达到饱和的原因
- 乐鑫 ESP-FAQ:快速查找常见问题
- CIA进行“嫁祸式攻击”?专家称维基解密对CIA的指控有些“过分”