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 实现分布式事务相关推荐

  1. Spring Cloud Eureka整合 Seata 实现分布式事务

    一.Seata 介绍 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的 ...

  2. Spring Cloud 整合 seata 实现分布式事务极简入门

    Spring Cloud 整合 seata 实现分布式事务极简入门 seata Spring Cloud 整合 seata 实现分布式事务极简入门 1. 概述 2. 部署nacos 3. 部署seat ...

  3. springCloud整合seata实现分布式事务

    seata简介 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式 ...

  4. Spring Cloud Alibaba系列四:集成 seata 实现分布式事务

    文章目录 Spring Cloud Alibaba系列四:集成 seata 实现分布式事务 前言 Seata 是什么? Seata 术语 安装 seata 1.创建 seata 数据库,并添加对应的表 ...

  5. Spring Boot之基于Dubbo和Seata的分布式事务解决方案

    转载自 Spring Boot之基于Dubbo和Seata的分布式事务解决方案 1. 分布式事务初探 一般来说,目前市面上的数据库都支持本地事务,也就是在你的应用程序中,在一个数据库连接下的操作,可以 ...

  6. 实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!

    今天这篇文章介绍一下Spring Cloud Gateway整合OAuth2.0实现认证授权,涉及到的知识点有点多,有不清楚的可以看下陈某的往期文章. 文章目录如下: 微服务认证方案 微服务认证方案目 ...

  7. Spring Cloud Gateway整合Nacos实现服务路由及集群负载均衡

    目录 一.序言 二.代码示例 1.父工程spring-cloud-gateway-learning 2.子工程spring-cloud-api-gateway (1) pom.xml (2) 配置文件 ...

  8. Spring Cloud Gateway 整合 knife4j 聚合接口文档

    当系统中微服务数量越来越多时,如果任由这些服务散落在各处,那么最终管理每个项目的接口文档将是一件十分麻烦的事情,单是记住所有微服务的接口文档访问地址就是一件苦差事了.当如果能够将所有微服务项目的接口文 ...

  9. 使用Seata解决分布式事务以及Seata的安装、配置和使用

    目录 事务的介绍 什么是本地事务? 分布式事务 分布式事务解决方案之seata Seata介绍 Seata是什么 Seata的分布式事务解决方案 Seata的核心组件 AT模式的工作流程 一阶段 二阶 ...

最新文章

  1. 苹果运行内存比较_决定手机流畅度到底是看CPU还是运行内存,你知道么?
  2. runtime error: invalid memory address or nil pointer dereference
  3. Android 插件化总结
  4. Shell下的环境变量
  5. [Vue源码分析] 模板的编译
  6. docker 发布tomcat项目_在docker中部署tomcat并且部署java应用程序的步骤详解
  7. CF938G Shortest Path Queries
  8. Sword pcre库函数学习三
  9. 学习OpenCV时 ,添加:#includeopencv2/core/core.hpp等头文件出现无法编译的错误
  10. HDU2544 最短路【Dijkstra算法】
  11. IPSEC 002 ---- Internet危机四伏,IPSec闪亮登场
  12. 【步骤详解】畅捷通T+Cloud无代码集成钉钉群机器人示例
  13. Java file.encoding
  14. XSS靶场练习 https://xss.haozi.me
  15. Log4J按照不同包名输出日志
  16. “智慧路灯”、“一杆多用”、“智慧灯杆”将成为新型智慧城市建设的重要决策部署
  17. 2021年焊工(初级)考试资料及焊工(初级)新版试题
  18. 致远OA自定义函数--正则表达式匹配校验
  19. 操作系统第七、八章习题
  20. 大数据在医疗领域应用有哪些挑战?

热门文章

  1. python报错No module named XXX解决方法
  2. ESP32-S2上使用SPI接口芯片DM9051NP转以太网的无线物联网网关开发指导
  3. 面向对象编程(OOP)
  4. 助眠好物推荐,帮助睡眠最好的办法
  5. thrift的使用介绍
  6. 多媒体计算机是指安装了什么部件的,多媒体计算机是指安装了什么的计算机
  7. java字符下落,重力球,加速下落减速上弹,重力下落,这段代码是看到网上一个关...
  8. caffe刚开始训练准确率很高,经过几次训练就达到饱和的原因
  9. 乐鑫 ESP-FAQ:快速查找常见问题
  10. CIA进行“嫁祸式攻击”?专家称维基解密对CIA的指控有些“过分”