Seata 的AT模式需求实战_04

接上一篇:Seata 与 Nacos Config配置中心整合_03

模拟下单场景:首先去在自己的本地创建一条下单记录,同时,还要去调用库存服务,执行减库存操作。

文章目录

          • 一、数据库部分
            • 1. 订单库创建
            • 2. 表结构初始化
            • 3. 库存数据库创建
            • 4. 库存表结构初始化
            • 5. 依赖新增
          • 二、订单微服务代码部分
            • 2.1. 创建实体类
            • 2.2. 创建接口类
            • 2.3. 调整控制层逻辑
            • 2.4. 修改配置文件
          • 三、库存微服务代码部分
            • 3.1. 创建实体类
            • 3.2. 接口库存Dao
            • 3.3. 容错代码
            • 3.4. 控制层逻辑调整
            • 3.5. 配置文件修改
            • 3.6. 初始化库存
            • 3.7. 容错代码简述
          • 四、测试验证
            • 4.1. 启动服务
            • 4.2. 发起第一轮请求
            • 4.3. 抛出异常
            • 4.4. 异常信息监控
            • 4.5. 流程梳理
            • 4.6. 数据库验证
            • 4.7. 发起第二轮请求
            • 4.8. 发起第三轮请求
            • 4.9. 数据库数据验证
            • 4.10. 发起第四轮请求
            • 4.11. 数据库验证

一、数据库部分
1. 订单库创建

新增数据库orderdb,
在这里插入图片描述

2. 表结构初始化

并创建订单表 和AT模式seata需要用到的undolog表
在这里插入图片描述

create table orderdb.order_tb
(id int auto_incrementprimary key,user_id int not null,product_id int not null
);
create table orderdb.undo_log
(id bigint auto_incrementprimary key,branch_id bigint not null,xid varchar(100) not null,context varchar(128) not null,rollback_info longblob not null,log_status int not null,log_created datetime not null,log_modified datetime not null,ext varchar(100) null,constraint ux_undo_logunique (xid, branch_id)
)
charset=utf8;
3. 库存数据库创建

新增数据库stockdb,并创建库存表 和AT模式seata需要用到的undolog表
在这里插入图片描述

4. 库存表结构初始化

并创建库存表 和AT模式seata需要用到的undolog表
在这里插入图片描述

create table stockdb.stock
(id int auto_incrementprimary key,count int not null,product_id int not null
);create table stockdb.undo_log
(id bigint auto_incrementprimary key,branch_id bigint not null,xid varchar(100) not null,context varchar(128) not null,rollback_info longblob not null,log_status int not null,log_created datetime not null,log_modified datetime not null,ext varchar(100) null,constraint ux_undo_logunique (xid, branch_id)
)
charset=utf8;
5. 依赖新增

在parent的pom.xml中新增依赖

        <!--分布式事务--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency><dependency><groupId>io.seata</groupId><artifactId>seata-all</artifactId><version>1.3.0</version></dependency><!--Lombok引入--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- Spring Boot JPA 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency>
二、订单微服务代码部分

我们对现在的order-serv订单服务基础上调整

2.1. 创建实体类
package com.gblfy.entity;import lombok.Data;import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;@Entity
@Table(name = "order_tb")
@Data
public class Order implements Serializable {public Order() {}@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;/*** 标题*/@Column(name = "product_id")private Integer productId;/*** 原价格*/@Column(name = "user_id")private Integer userId;}
2.2. 创建接口类
package com.gblfy.dao;import com.gblfy.entity.Order;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;@Repository
public interface OrderResposity extends JpaRepository<Order, Integer> {
}

业务代码修改
原代码
在这里插入图片描述

2.3. 调整控制层逻辑

调整后代码逻辑如下

package com.gblfy.controller;import com.gblfy.dao.OrderResposity;
import com.gblfy.entity.Order;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;@RestController
public class OrderController {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate OrderResposity orderResposity;//http://localhost:8000/order/create?productId=11&userId=11222@GlobalTransactional(timeoutMills = 300000, name = "spring-cloud-demo-tx")@GetMapping("/order/create")public String createOrder(Integer productId, Integer userId) {Order order = new Order();order.setProductId(productId);order.setUserId(userId);orderResposity.save(order);String result = restTemplate.getForObject("http://stock-serv/stock/reduce/" + productId, String.class);if (!result.equals("success")) {throw new RuntimeException();}return result;}
}
2.4. 修改配置文件
server:port: 9002
spring:datasource:url: jdbc:mysql://192.168.159.105:3306/orderdbusername: rootpassword: 123456cloud:nacos:discovery:service: order-servgroup: SEATA_GROUPserver-addr: 192.168.159.105:8848application:name: order-serv
seata:enabled: truetx-service-group: order-serviceconfig:type: nacosnacos:namespace: publicserverAddr: 192.168.159.105:8848group: SEATA_GROUPuserName: "nacos"password: "nacos"registry:type: nacosnacos:application: seata-serverserverAddr: 192.168.159.105:8848group: SEATA_GROUPnamespace: publicuserName: "nacos"password: "nacos"
三、库存微服务代码部分

我们对现在的stock-serv库存服务基础上调整

3.1. 创建实体类
package com.gblfy.entity;import lombok.Data;import javax.persistence.*;
import java.io.Serializable;@Entity
@Table(name = "stock")
@Data
public class Stock implements Serializable {public Stock() {}@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;/*** 标题*/@Column(name = "count")private Integer count;/****/@Column(name = "product_id")private Integer productId;}
3.2. 接口库存Dao
package com.gblfy.dao;import com.gblfy.entity.Stock;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;@Repository
public interface StockResposity extends JpaRepository<Stock, Integer> {// 通过商品ID查询库存信息public Stock getFirstByProductId(Integer productId);
}
3.3. 容错代码

在StockApplication 中新增一个类的定义 用于获取随机的boolean值,模拟随机报错的情况

package com.gblfy;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;import java.util.Random;@SpringBootApplication
public class StockApplication {public static void main(String[] args) {SpringApplication.run(StockApplication.class);}@Beanpublic Random generate(){return new Random();}
}
3.4. 控制层逻辑调整

修改库存controller,减库存直接操作数据库

package com.gblfy.controller;import com.gblfy.dao.StockResposity;
import com.gblfy.entity.Stock;
import io.seata.core.context.RootContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import java.util.Random;/*** 库存服务** @author gblfy* @date 2021/8/19*/
@RestController
public class StockController {private static final Logger LOGGER = LoggerFactory.getLogger(StockController.class);@Autowiredprivate StockResposity resposity;@Autowiredprivate Random random;@GetMapping("/stock/reduce/{productId}")public String reduce(@PathVariable Integer productId) {LOGGER.info("Storage Service Begin ... xid: " + RootContext.getXID());if (random.nextBoolean()) {throw new RuntimeException("this is a mock Exception");}Stock stock = resposity.getFirstByProductId(productId);if (stock != null) {stock.setCount(stock.getCount() - 1);resposity.save(stock);return "success";}return "fail";}
}
3.5. 配置文件修改
server:port: 8002
spring:datasource:url: jdbc:mysql://192.168.159.105:3306/stockdbusername: rootpassword: 123456cloud:nacos:discovery:service: stock-servgroup: SEATA_GROUPserver-addr: 192.168.159.105:8848application:name: stock-serv
seata:enabled: truetx-service-group: order-serviceconfig:type: nacosnacos:namespace: publicserverAddr: 192.168.159.105:8848group: SEATA_GROUPuserName: "nacos"password: "nacos"registry:type: nacosnacos:application: seata-serverserverAddr: 192.168.159.105:8848group: SEATA_GROUPnamespace: publicuserName: "nacos"password: "nacos"

tx-service-group:的值从nacos这里取,必须保持一致
在这里插入图片描述

3.6. 初始化库存

在扣库存微服务初始化数据

INSERT INTO `stock` VALUES (1, 100, 1);
3.7. 容错代码简述

这里在扣库存服务块中抛出异常,是为了模拟在创建订单库完成后,扣库存失败的场景。验证订单数据库的数据是否产生,如果没有产生从而说明分布式事务生效了,相当于跨库进行事物的回滚。

四、测试验证
4.1. 启动服务

启动订单服务
在这里插入图片描述
启动扣库存服务
在这里插入图片描述
在这里插入图片描述

4.2. 发起第一轮请求

http://localhost:9002/order/create?productId=11&userId=11222

4.3. 抛出异常

发生错误,进入咱们的容错逻辑
在这里插入图片描述

4.4. 异常信息监控

扣库存微服务模块
在这里插入图片描述
订单模块微服务
在这里插入图片描述

4.5. 流程梳理

①请求下单服务
②创建订单并在订单数据库中插入一条订单数据
③调用扣库存微服务
④发生异常
如果分布式事务生效的话,事务的原子性一致性应该不会产生脏数据。对吧!

4.6. 数据库验证

库存为服务发生异常后,先查看订单数据库是否产生订单数据
在这里插入图片描述
再查看扣库存数据库是否扣库存成功
在这里插入图片描述
从以上截图中可以看出咱们的分布式事务生效了,既没有产生脏数据,有没有扣库存成功,符合预期。

4.7. 发起第二轮请求

再次发起请求,继续测试,由于我扣库存的数据库中只有productId=1的商品,不管我请求多少次,都会失败,脏数据不会产生扣库存也会失败
http://localhost:9002/order/create?productId=11&userId=11222

4.8. 发起第三轮请求

把请求的地址调整成正确的路径,再次请求测试
http://localhost:9002/order/create?productId=1&userId=11222

终于有成功的了
在这里插入图片描述

4.9. 数据库数据验证

查看订单数据库是是否产生订单数据
在这里插入图片描述
从图中,可以看出差生了一条订单数据
在查看扣库存数据是否也减少了呢
在这里插入图片描述
从上图可以看出,产生一条订单数据,就会减少一个库存,符合咱们的预期,分布式事务也生效了。

4.10. 发起第四轮请求

继续提高并发测试,测试结果有的成功了,有的失败了。

4.11. 数据库验证

产生了5条订单数据
在这里插入图片描述
相应的库存也减少了5个
在这里插入图片描述
测试验证到此为止!

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

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

相关文章

国产数据库技术全面破冰,金融核心系统打破国外巨头垄断指日可待

作者 | 马超责编 | 伍杏玲头图 | CSDN下载自东方IC出品 | CSDN&#xff08;ID:CSDNnews&#xff09; 作为一名金融IT人&#xff0c;打造完全自主掌控的金融核心&#xff0c;是我们心中的梦想。年轻的读者可能不太了解过去金融系统的建设往事&#xff0c;我们一直沿用至2013年的…

Go语言出现后,Java还是最佳选择吗?

阿里妹导读&#xff1a;随着大量新生的异步框架和支持协程的语言(如Go)的出现&#xff0c;在很多场景下操作系统的线程调度成为了性能的瓶颈&#xff0c;Java也因此被质疑是否不再适应最新的云场景了。4年前&#xff0c;阿里JVM团队开始自研Wisp2&#xff0c;将Go语言的协程能力…

为何小程序上线了,他们的内心却留下遗憾?

前言 出于多端投放和开放生态的考虑&#xff0c;闲鱼开始接入整个阿里小程序体系。闲鱼在9月份迅速上线了第一个小程序鱼塘小程序&#xff0c;由于刚接触不熟悉小程序体系&#xff0c;整体性能上有比较大的优化空间&#xff0c;主要表现在以下问题&#xff1a; 小程序加载慢&…

高德亿级流量接入层服务的演化之路

2019杭州云栖大会上&#xff0c;高德地图技术团队向与会者分享了包括视觉与机器智能、路线规划、场景化/精细化定位时空数据应用、亿级流量架构演进等多个出行技术领域的热门话题。现场火爆&#xff0c;听众反响强烈。我们把其中的优秀演讲内容整理成文并陆续发布出来&#xff…

一篇与众不同的 String、StringBuilder 和 StringBuffer 详解

来源 | 程序员 cxuan责编 | Carol封图 | CSDN 付费下载自视觉中国这是一道老生常谈的问题了&#xff0c;字符串是不仅是 Java 中非常重要的一个对象&#xff0c;它在其他语言中也存在。比如 C、Visual Basic、C# 等。字符串使用 String 来表示&#xff0c;字符串一旦被创建出来…

Ververica Platform-阿里巴巴全新Flink企业版揭秘

摘要&#xff1a;2019云栖大会大数据 & AI专场&#xff0c;阿里巴巴资深技术专家王峰带来“Ververica Platform-阿里巴巴全新Flink企业版揭秘”的演讲。本文主要从Ververica由来开始谈起&#xff0c;着重讲了Ververica Platform的四个核心插件App Manager、Libra Service、…

滴滴经验分享:SQLFlow如何让运营专家用上AI?

蚂蚁金服过去十五年&#xff0c;重塑支付改变生活&#xff0c;为全球超过十二亿人提供服务&#xff0c;这些背后离不开技术的支撑。在2019杭州云栖大会上&#xff0c;蚂蚁金服将十五年来的技术沉淀&#xff0c;以及面向未来的金融技术创新和参会者分享。我们将其中的优秀演讲整…

秒杀场景_Sentinel在秒杀场景的应用_05

上一篇解决了在高并发秒杀场景下的超卖问题&#xff0c;这一篇主要解决如何利用Sentinel防止服务器雪崩。 文章目录一、 商品微服务集成Sentinel1. 引入依赖2. 添加配置二、 秒杀微服务集成Sentinel2.1. 引入依赖2.2. 添加配置三、 Sentinel流控规则3.1. 登录Sentinel3.2. 请求…

SQLServer 密码验证登录18456错误解决方案

一、SQLServer18456错误 二、解决方案 第一步&#xff1a;确定这两个服务都是开启状态 &#xff08;1&#xff09;点击管理 &#xff08;2&#xff09;点击服务和应用程序 &#xff08;3&#xff09;确定这两个都是开启状态 &#xff08;4&#xff09;开启方法&#xff0c;右…

80% 的 Java 焦虑,都可以被这张图解决

昨晚&#xff0c;我在路口等车的时候&#xff0c;听到几个人在那讨论问题&#xff1a;“之前我用 jprofiler 监控 jvm 里的对象&#xff0c;当老年代满了&#xff0c;我手动触发一次 fgc&#xff0c;发现只能回收一半&#xff0c;再触发一次&#xff0c;就完全回收&#xff0c;…

直击案发现场!TCP 10倍延迟的真相是?

阿里妹导读&#xff1a;什么是经验&#xff1f;就是遇到问题&#xff0c;解决问题&#xff0c;总结方法。遇到的问题多了&#xff0c;解决的办法多了&#xff0c;经验自然就积累出来了。今天的文章是阿里技术专家蛰剑在工作中遇到的一个问题引发的对TCP性能和发送接收Buffer关系…

今日头条在消息服务平台和容灾体系建设方面的实践与思考

本篇文章整理自今日头条的沈辉在 RocketMQ 开发者沙龙中的演讲&#xff0c;主要和大家分享一下&#xff0c;RocketMQ 在微服务架构下的实践和容灾体系建设。沈辉是今日头条的架构师&#xff0c;主要负责 RocketMQ 在头条的落地以及架构设计&#xff0c;参与消息系统的时间大概一…

秒杀场景_同步秒杀分析和实战_01

文章目录一、应用部署准备1. mysql安装部署2. redis安装部署3. nacos安装部署二、数据库准备2.1. 创建数据库2.2. 初始化表结构2.3. 搭建微服务父工程三、商品模块微服务3.1. 搭建product-serv模块3.2. 配置yml3.3. 实体3.4. 接口3.5. service3.6. controller3.7. 启动类四、秒…

Kali 2020版 Linux操作系统解决系统语言问题(英文--中文)

文章目录一、更新镜像源&#xff08;1&#xff09;进入配置文件&#xff08;2&#xff09;更新软件包二、修改配置(1)打开终端输入以下数据(2)修改配置文件三、安装中文字体四、restart(重启Kali Linux系统)一、更新镜像源 镜像源有很多&#xff0c;我这里提供了阿里云的镜像源…

Spark Relational Cache实现亚秒级响应的交互式分析

本次分享主要分为以下四个方面&#xff1a; 项目介绍技术分析如何使用性能分析 一、项目介绍 项目背景 阿里云EMR是一个开源大数据解决方案&#xff0c;目前EMR上面已经集成了很多开源组件&#xff0c;并且组件数量也在不断的增加中。EMR下层可以访问各种各样的存储&#xf…

阿里巴巴 Kubernetes 应用管理实践中的经验与教训

导读&#xff1a;云原生时代&#xff0c;Kubernetes 的重要性日益凸显。然而&#xff0c;大多数互联网公司在 Kubernetes 上的探索并非想象中顺利&#xff0c;Kubernetes 自带的复杂性足以让一批开发者望而却步。本文中&#xff0c;阿里巴巴技术专家孙健波在接受采访时基于阿里…

那些被大数据时代抛弃的人

作者 | 衣公子来源 | 衣公子的剑&#xff08;ID&#xff1a;yigongzidejian&#xff09;前言2000年&#xff0c;微软如日中天。有人问比尔盖茨&#xff08;Bill Gates&#xff09;对于IT行业的看法。盖茨说&#xff0c;挺好的&#xff0c;就是有点noise。 noise&#xff0c;本意…

秒杀场景_多线程异步抢单队列分析与实现_02

文章目录1. 实体2. Service改造3. 启动类1. 实体 package com.gblfy.entity;import java.io.Serializable;/*** 用户排队抢单信息实体*/Data public class SkillEntity implements Serializable {private Long productId;private String userId; }2. Service改造 SkillGoodSe…

AI赋能DevOps:数据驱动的全栈工程师实践

DevOps是什么&#xff1f; 对于传统的软件研发而言&#xff0c;开发&#xff0c;测试&#xff0c;运维&#xff0c;运营&#xff0c;有不同的岗位进行分工协作&#xff0c;以保证质量和专业度&#xff0c;同一件事情&#xff0c;依赖不同岗位的排期、沟通、协调&#xff0c;效率…

阿里HBase高可用8年“抗战”回忆录

2017年开始阿里HBase走向公有云&#xff0c;我们有计划的在逐步将阿里内部的高可用技术提供给外部客户&#xff0c;目前已经上线了同城主备&#xff0c;将作为我们后续高可用能力发展的一个基础平台。本文分四个部分回顾阿里HBase在高可用方面的发展&#xff1a;大集群、MTTF&a…