Seata(分布式事务集成测试和总结)

文章目录

    • 1.集成测试
        • 1.集成测试正常下单
          • 1.步骤
          • 2.浏览器访问 http://localhost:10008/order/save?userId=666&productId=1&nums=1&money=100
          • 3.注意事项和细节
        • 2.集成测试模拟异常
          • 1.步骤
            • 1.com/sun/springcloud/controller/StorageController.java 休眠12s,模拟openfeign超时
            • 2.仍然按照正常步骤启动并测试
            • 3.预测结果
          • 2.执行前数据库状态
            • order表
            • account表
            • storage表
          • 3.浏览器输入 http://localhost:10008/order/save?userId=666&productId=1&nums=2&money=200,12s后查看数据库状态
            • order表
            • account表(这里在写sql时并没有计算数量,所以确实应该减去200)
            • storage表(库存减2)
        • 3.集成测试分布式事务控制
          • 1.在com/sun/springcloud/service/Impl/OrderServiceImpl.java 的save方法加上@GlobalTransactional进行分布式事务控制
          • 2.测试步骤
          • 3.全部启动后查看nacos注册情况
          • 4.测试前数据库状态
          • 5.浏览器请求 http://localhost:10008/order/save?userId=666&productId=1&nums=1&money=100
          • 5.注意事项
    • 2.seata分布式事务总结
        • 1.工作机制
        • 2.seata的使用流程
          • 1.安装
          • 2.修改 D:\seata\conf\file.conf文件
            • 1.修改事务组(需要进行分布式事务控制的微服务在同一组)
            • 2.修改日志存储模式为db
            • 3.修改数据库(MySQL5.7)连接信息
          • 3.修改registry.conf 配置注册中心nacos(seata需要注册到nacos)
          • 4.创建seata数据库和表
            • 1.创建seata数据库
            • 2.复制db_store.sql的内容,创建需要的表
          • 5.启动nacos和seata进行测试,seata会注册到nacos
          • 6.为每个需要分布式事务控制的数据库执行 db_undo_log.sql,创建undo_log表,用于事务回滚
          • 7.pom.xml引入依赖
          • 8.application.yml
          • 9.D:\seata\conf下的两个配置文件复制到src/main/resources下并修改
            • 1.将file.conf复制到src/main/resources下,然后修改这行,`seata的服务ip+端口`以及`db`根据实际情况修改(前面是修改过的)
            • 2.registry.conf复制到src/main/resources下,然后配置注册中心nacos(前面也配过,直接复制即可)
            • 3.最终的文件目录
          • 10.进行业务逻辑编写
            • 1.创建实体类
            • 2.dao层
            • 3.service层
            • 4.controller层
          • 11.两个常规配置类
            • 1.MyBatisConfig.java 配置类,依赖注入所有Mapper接口(不用加@Mapper注解了)
            • 2.DataSourceProxyConfig.java 配置数据源代理为 seata
          • 12.创建主启动类(示例)
          • 13.OpenFeign远程调用细节
            • 1.在前面的依赖中已经引入了OpenFeign,并且在主启动类中也开启了Feign客户端
            • 2.service接口声明需要远程调用的controller
            • 3.远程调用的方式
            • 4.谁可以远程调用

1.集成测试

1.集成测试正常下单
1.步骤

image-20240331195720151

2.浏览器访问 http://localhost:10008/order/save?userId=666&productId=1&nums=1&money=100

image-20240331200211635

image-20240331200315814

image-20240331200345159

image-20240331200405815

image-20240331200414455

3.注意事项和细节

image-20240331201240727

2.集成测试模拟异常
1.步骤
1.com/sun/springcloud/controller/StorageController.java 休眠12s,模拟openfeign超时

image-20240331204813269

2.仍然按照正常步骤启动并测试

image-20240331195720151

3.预测结果
  • 保存订单,扣减账户余额,扣减库存成功!但是修改订单状态失败,也就是status是0!

image-20240331202326884

image-20240331202503115

2.执行前数据库状态
order表

image-20240331204912334

account表

image-20240331204932277

storage表

image-20240331205004551

3.浏览器输入 http://localhost:10008/order/save?userId=666&productId=1&nums=2&money=200,12s后查看数据库状态
order表

image-20240331205124780

account表(这里在写sql时并没有计算数量,所以确实应该减去200)

image-20240331205149516

storage表(库存减2)

image-20240331210545726

3.集成测试分布式事务控制
1.在com/sun/springcloud/service/Impl/OrderServiceImpl.java 的save方法加上@GlobalTransactional进行分布式事务控制

image-20240401085848112

2.测试步骤

image-20240331195720151

3.全部启动后查看nacos注册情况

image-20240401090152198

4.测试前数据库状态

image-20240401090227123

image-20240401090238720

image-20240401090249370

5.浏览器请求 http://localhost:10008/order/save?userId=666&productId=1&nums=1&money=100

image-20240401090600011

image-20240401090536951

image-20240401090546928

image-20240401090555538

5.注意事项

image-20240401091116586

2.seata分布式事务总结

1.工作机制

image-20240401100528767

2.seata的使用流程
1.安装
2.修改 D:\seata\conf\file.conf文件
1.修改事务组(需要进行分布式事务控制的微服务在同一组)

image-20240331094307051

2.修改日志存储模式为db

image-20240331094402339

3.修改数据库(MySQL5.7)连接信息

在这里插入图片描述

3.修改registry.conf 配置注册中心nacos(seata需要注册到nacos)

image-20240331095851458

image-20240331095834040

4.创建seata数据库和表
1.创建seata数据库
# 创建数据库 seata
create database seata;
use seata;
2.复制db_store.sql的内容,创建需要的表

image-20240401101509841

image-20240331095307621

5.启动nacos和seata进行测试,seata会注册到nacos
6.为每个需要分布式事务控制的数据库执行 db_undo_log.sql,创建undo_log表,用于事务回滚

image-20240331103729957

7.pom.xml引入依赖
  • 注意这里引入的nacos是nacos-discovery starter,没有整合Seata之前引入的跟这个不一样!!!
    <dependencies><!-- 提示 application.yml --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!-- 引入 openfeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- 在微服务模块引入 nacos-discovery starter --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--seata--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><exclusions><!-- 排除自带的 seata-all --><exclusion><artifactId>seata-all</artifactId><groupId>io.seata</groupId></exclusion></exclusions></dependency><!-- 引入指定版本的 io.seata --><dependency><groupId>io.seata</groupId><artifactId>seata-all</artifactId><version>0.9.0</version></dependency><!-- springboot web starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 如果在子工程/模块指定了 version,则以指定为准 --></dependency><!--1. starter-actuator 是 springboot 程序的监控系统,可以实现健康检查,info 信息等2. 访问 http://localhost:10000/actuator 可以看到相关链接, 还可以做相关设置. --><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- mybatis --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!-- druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><!-- 这里我们重新指定一下 version 因为父项目中没有对这个依赖进行版本仲裁--><version>1.1.13</version></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- jdbc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 公共模块的jar包 --><dependency><groupId>org.example</groupId><artifactId>e_commerce_center-common-api</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>
8.application.yml
server:port: 10010 # 配置服务端口
spring:application:name: seata-storage-micor-service # 配置服务的名称,名字任意这里与项目名保持一致cloud:alibaba:seata:  # 配置seatatx-service-group: sun_order_tx_group # 自定义事务组名称,与\conf\file.conf保持一致nacos: # 配置nacosdiscovery:server-addr: localhost:8848datasource: # 配置数据源driver-class-name: com.mysql.jdbc.Driver# 别忘记创建数据库之后修改数据库名称url: username: password: 
logging:  # 配置seata日志级别level:io:seata: info
mybatis:mapperLocations: classpath:mapper/*.xml # 扫描所有Mapper.xmlconfiguration:map-underscore-to-camel-case: true # 开启驼峰命名
9.D:\seata\conf下的两个配置文件复制到src/main/resources下并修改
1.将file.conf复制到src/main/resources下,然后修改这行,seata的服务ip+端口以及db根据实际情况修改(前面是修改过的)

image-20240331112838536

2.registry.conf复制到src/main/resources下,然后配置注册中心nacos(前面也配过,直接复制即可)

image-20240331113355613

3.最终的文件目录

image-20240331113408627

10.进行业务逻辑编写
1.创建实体类
  • 如果数据库中的数据是sun_name则在实体类中可以编写为sunName,不过这样需要在application.yml中开启自动驼峰命名(上面配置了)
  • 这个就相当于在每个Mapper.xml中加了一个resultMap映射,如果实体类属性和表的字段可以被自动驼峰命名所映射那么就不需要再写resultMap
2.dao层
  • Mapper接口注入容器
  • Mapper接口的@Param注解一旦指定,就不需要在xml实现的时候指定参数类型了,直接使用#{}来取出数据即可
  • Mapper.xml在application.yml中已经配置了自动扫描
3.service层
  • service接口编写
  • service实现类注入容器
4.controller层
  • 注入容器
  • 在微服务中如果使用GetMapping则参数需要添加@RequestParam
  • 如果使用PostMapping则参数需要添加@RequestBody
11.两个常规配置类
1.MyBatisConfig.java 配置类,依赖注入所有Mapper接口(不用加@Mapper注解了)
package com.sun.springcloud.config;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;/*** Description: MyBatis配置类,扫描所有Mapper接口,这样就不用在每个Mapper接口上添加@Mapper注解** @Author sun* @Create 2024/3/31 13:16* @Version 1.0*/
@MapperScan("com.sun.springcloud.dao")
@Configuration
public class MyBatisConfig {
}
2.DataSourceProxyConfig.java 配置数据源代理为 seata
  • 这里需要注意:配置文件中的mybatis.mapperLocations是以驼峰命名的
package com.sun.springcloud.config;import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import javax.sql.DataSource;/*** Description: 配置数据源的代理是 seata** @Author sun* @Create 2024/3/31 13:28* @Version 1.0*/
@Configuration
public class DataSourceProxyConfig {// 配置文件中的mybatis.mapperLocations@Value("${mybatis.mapperLocations}")private String mapperLocations; // 1.mybatis的mapper文件位置// 配置数据源@Bean@ConfigurationProperties(prefix = "spring.datasource") // 2.读取配置文件中的数据源配置public DataSource druidDataSource() {return new DruidDataSource();}// 配置数据源代理为seata的DataSourceProxy@Bean // 配置数据源代理引入的包: io.seata.rm.datasource.DataSourceProxypublic DataSourceProxy dataSourceProxy(DataSource dataSource) {return new DataSourceProxy(dataSource);}// 配置SqlSessionFactory为seata的SqlSessionFactoryBean@Bean // 配置SqlSessionFactory,常规配置public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy)throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean =new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSourceProxy);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations)); // 3.mybatis的mapper文件位置sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());return sqlSessionFactoryBean.getObject();}
}
12.创建主启动类(示例)
package com.sun.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;/*** Description:** @Author sun* @Create 2024/3/31 13:37* @Version 1.0*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) // 取消数据源的自动创建,使用代理数据源
@EnableDiscoveryClient // 开启服务发现
@EnableFeignClients // 开启Feign客户端
public class SeataStorageMicroServiceApplication10010 {public static void main(String[] args) {SpringApplication.run(SeataStorageMicroServiceApplication10010.class, args);}
}
13.OpenFeign远程调用细节
1.在前面的依赖中已经引入了OpenFeign,并且在主启动类中也开启了Feign客户端
2.service接口声明需要远程调用的controller
  • 这里的FeignClient可以进行服务发现,得到要调用的服务的ip+端口+上下文路径
  • 这里的RequestMapping可以找到远程调用的服务的资源路径,与服务发现的路径进行拼接即可找到指定资源
  • 具体声明的方式就是
    1. 添加@FeignClient注解,指定要远程调用服务的application-name(注意不能带_)
    2. 将需要调用的controller直接复制过来,然后去掉方法体即可
package com.sun.springcloud.service;import com.sun.springcloud.util.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;/*** Description:** @Author sun* @Create 2024/3/31 16:19* @Version 1.0*/
@FeignClient(value = "seata-storage-micor-service")
public interface StorageService {@RequestMapping("/storage/reduce")public Result reduce(Long productId, Integer nums);
}
3.远程调用的方式
  • 通过依赖注入针对service接口的代理对象进行远程调用
4.谁可以远程调用
  • service接口实现类
  • controller

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/796121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动驾驶执行层 - 线控底盘基础原理(非常详细)

自动驾驶执行层 - 线控底盘基础原理(非常详细) 附赠自动驾驶学习资料和量产经验&#xff1a;链接 1. 前言 1.1 线控的对象 在自动驾驶行业所谓的“感知-定位-决策-执行”的过程中&#xff0c;在末端的执行层&#xff0c;车辆需要自主执行决策层所给出的指令&#xff0c;具体…

leetcode(HOT100)——链表篇

1、相交链表 本题思路就是定义两指针&#xff0c;指向两链表的同一起跑线&#xff0c;然后共同往前走&#xff0c;边走边判断两链表的节点是否相等&#xff0c; 代码如下&#xff1a; /*** Definition for singly-linked list.* public class ListNode {* int val;* L…

Android14应用启动流程(源码+Trace)

1.简介 应用启动过程快的都不需要一秒钟&#xff0c;但这整个过程的执行是比较复杂的&#xff0c;无论是对手机厂商、应用开发来说启动速度也是核心用户体验指标之一&#xff0c;本文采用Android14源码与perfetto工具进行解析。 源码参考地址&#xff1a;Search trace分析工…

2024.4.5|牛客小白月赛90

2024.4.5|牛客小白月赛90 A.小A的文化节 B.小A的游戏 C.小A的数字 D.小A的线段&#xff08;easy version&#xff09; E.小A的任务 F.小A的线段&#xff08;hard version&#xff09; 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c…

[报错解决]源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示。

目录 报错信息解决办法 spring整合mvc时&#xff0c;遇到的404报错&#xff0c;梳理mvc知识供参考供 报错信息 解决办法 Controller RequestMapping("user") public class UserController {//spring整合webmvc// 请求地址 http://localhost:7070/user/quickRequest…

数据字典

文章目录 一、需求分析二、表设计&#xff08;两张表&#xff09;三、功能实现3.1 数据字典功能3.1.1 列表功能3.1.2 新增数据字典3.1.3 编辑数据字典 3.2 数据字典明细3.2.1 列表功能3.2.2 新增字典明细3.2.3 编辑字典明细 3.3 客户管理功能3.3.1 列表功能3.3.2 新增用户3.3.3…

Golang | Leetcode Golang题解之第11题盛最多水的容器

题目&#xff1a; 题解&#xff1a; func maxArea(height []int) int {res : 0L : 0R : len(height) - 1for L < R {tmp : math.Min(float64(height[L]), float64(height[R]))res int(math.Max(float64(res), tmp * float64((R - L))))if height[L] < height[R] {L} el…

【环境变量】基本概念理解 | 查看环境变量echo | PATH的应用和修改

目录 前言 基本概念&理解 注意的点 查看环境变量方法 PATH环境变量 PTAH应用系统指令 PTAH应用用户程序 命令行的修改&#xff08;内存级&#xff09; 配置文件的修改 windows环境变量 大家天天开心&#x1f642; bash进程的流程。环境变量在系统指令和用户…

Linux网卡IP地址配置错误的影响

在Linux系统中&#xff0c;网络配置是保持系统顺畅运行的关键一环。正确配置网卡的IP地址对于确保网络通信的准确性和效率至关重要。然而&#xff0c;如果在这个过程中发生错误&#xff0c;可能会带来一系列问题。让我们一起探讨一下&#xff0c;如果Linux网卡的IP地址配置错误…

Python+Yolov8框选位置目标识别人数统计计数

程序示例精选 PythonYolov8框选位置目标识别人数统计计数 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《PythonYolov8框选位置目标识别人数统计计数》编写代码&#xff0c;代码整洁&#…

测开——基础理论面试题整理

1. 测试流程 需求了解分析需求评审制定测试计划【包括测试人员、时间、每人负责的模块、测试的风险项以及预防】编写自动化测试用例 —— 测试评审【尽量丰富测试点】编写测试框架和脚本&#xff08;若是功能测试 可省去这步骤&#xff09;执行测试提交缺陷报告测试分析与评审…

Coursera上托福专项课程02:TOEFL Speaking and Writing Sections Skills Mastery 学习笔记

TOEFL Speaking and Writing Sections Skills Mastery Course Certificate 本文是学习 https://www.coursera.org/learn/toefl-speaking-writing-sections-skills-mastery 这门课的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 TOEFL Speaking and Writing…

docker-ce部署

目录 1. 更新软件包列表 2. 安装必要的软件包&#xff0c;以允许 apt 使用 HTTPS 3. 添加 Docker 的官方 GPG 密钥 4. 设置 Docker CE 的稳定存储库 5. 再次更新包索引以及安装 Docker CE 6. 验证 Docker CE 是否正确安装 7. 将当前用户添加到 docker 用户组&#xff0c;…

Linux之shell脚本编辑工具awk

华子目录 概念工作流程工作图流程&#xff08;按行处理&#xff09; awk程序执行方式1.通过命令行执行awk程序实例 2.awk命令调用脚本执行实例 3.直接使用awk脚本文件调用实例 awk命令的基本语法格式BEGIN模式与END模式实例awk的输出 记录和域&#xff08;记录表示数据行&#…

【陈老板赠书活动 - 25期】- 《Effective Java》

陈老老老板&#x1f9d9;‍♂️ &#x1f46e;‍♂️本文专栏&#xff1a;赠书活动专栏&#xff08;为大家争取的福利&#xff0c;免费送书&#xff09; &#x1f934;本文简述&#xff1a;活就像海洋,只有意志坚强的人,才能到达彼岸。 &#x1f473;‍♂️上一篇文章&#xff…

行人重识别项目 | 基于Pytorch实现ReID行人重识别算法

项目应用场景 面向行人重识别场景&#xff0c;项目具有轻量化 (训练的时候也只需要 2GB 的显存占用)、性能好 (只使用 softmax 损失就能够达到 Rank188.24%, mAP70.68%)&#xff0c;另外提供友好的上手项目流程教程 项目效果&#xff1a; 项目流程 > 具体参见项目内README.…

利用Flutter混淆工具提高应用的反编译难度

在移动应用开发中&#xff0c;保护应用代码安全至关重要。Flutter 提供了简单易用的混淆工具&#xff0c;帮助开发者在构建 release 版本应用时有效保护代码。本文将介绍如何在 Flutter 应用中使用混淆&#xff0c;并提供了相关的操作步骤和注意事项。 &#x1f4dd; 摘要 本…

第十四届蓝桥杯大赛软件赛省赛

第十四届蓝桥杯大赛软件赛省赛 2.日期统计 小蓝现在有一个长度为 100 的数组&#xff0c;数组中的每个元素的值都在 0 到 9 的范围之内。 数组中的元素从左至右如下所示&#xff1a; 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 …

【Linux】Linux C 编程

在 Windows 下编程首先就是安装对应的 IDE &#xff0c;然后在 IDE 里面进行代码编写和编译&#xff0c;但是在 Linux 下&#xff0c;这两个部分是分开的&#xff0c;比如我们可以使用 vim 编辑器编写代码&#xff0c;然后用 gcc 编译器编译代码。Ubuntu 下有一些可以进行编程的…

03-JAVA设计模式-工厂模式详解

工厂模式 工厂设计模式是一种创建型设计模式&#xff0c;它提供了一种封装对象创建过程的机制&#xff0c;将对象的创建与使用分离。 这种设计模式允许我们在不修改客户端代码的情况下引入新的对象类型。 在Java中&#xff0c;工厂设计模式主要有三种形式&#xff1a;简单工厂…