深情密码免费观看网站,2021百度seo,天津建设网安全员成绩查询,电子商务网站采用的开发技术接上一篇#xff1a;Seata 与 Nacos Config配置中心整合_03 模拟下单场景#xff1a;首先去在自己的本地创建一条下单记录#xff0c;同时#xff0c;还要去调用库存服务#xff0c;执行减库存操作。 文章目录一、数据库部分1. 订单库创建2. 表结构初始化3. 库存数据库创建… 接上一篇Seata 与 Nacos Config配置中心整合_03 模拟下单场景首先去在自己的本地创建一条下单记录同时还要去调用库存服务执行减库存操作。 文章目录一、数据库部分1. 订单库创建2. 表结构初始化3. 库存数据库创建4. 库存表结构初始化5. 依赖新增二、订单微服务代码部分2.1. 创建实体类2.2. 创建接口类2.3. 调整控制层逻辑2.4. 修改配置文件三、库存微服务代码部分3.1. 创建实体类3.2. 接口库存Dao3.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)
)
charsetutf8;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)
)
charsetutf8;5. 依赖新增
在parent的pom.xml中新增依赖 !--分布式事务--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-seata/artifactId/dependencydependencygroupIdio.seata/groupIdartifactIdseata-all/artifactIdversion1.3.0/version/dependency!--Lombok引入--dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency!--mysql--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId/dependency!-- Spring Boot JPA 依赖 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-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() {}IdGeneratedValue(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 JpaRepositoryOrder, 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?productId11userId11222GlobalTransactional(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: nacospassword: nacosregistry:type: nacosnacos:application: seata-serverserverAddr: 192.168.159.105:8848group: SEATA_GROUPnamespace: publicuserName: nacospassword: 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() {}IdGeneratedValue(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 JpaRepositoryStock, 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: nacospassword: nacosregistry:type: nacosnacos:application: seata-serverserverAddr: 192.168.159.105:8848group: SEATA_GROUPnamespace: publicuserName: nacospassword: nacostx-service-group:的值从nacos这里取必须保持一致 3.6. 初始化库存
在扣库存微服务初始化数据
INSERT INTO stock VALUES (1, 100, 1);3.7. 容错代码简述
这里在扣库存服务块中抛出异常是为了模拟在创建订单库完成后扣库存失败的场景。验证订单数据库的数据是否产生如果没有产生从而说明分布式事务生效了相当于跨库进行事物的回滚。
四、测试验证
4.1. 启动服务
启动订单服务 启动扣库存服务
4.2. 发起第一轮请求
http://localhost:9002/order/create?productId11userId11222
4.3. 抛出异常
发生错误进入咱们的容错逻辑
4.4. 异常信息监控
扣库存微服务模块 订单模块微服务
4.5. 流程梳理
①请求下单服务 ②创建订单并在订单数据库中插入一条订单数据 ③调用扣库存微服务 ④发生异常 如果分布式事务生效的话事务的原子性一致性应该不会产生脏数据。对吧
4.6. 数据库验证
库存为服务发生异常后先查看订单数据库是否产生订单数据 再查看扣库存数据库是否扣库存成功 从以上截图中可以看出咱们的分布式事务生效了既没有产生脏数据有没有扣库存成功符合预期。
4.7. 发起第二轮请求
再次发起请求继续测试由于我扣库存的数据库中只有productId1的商品不管我请求多少次都会失败脏数据不会产生扣库存也会失败 http://localhost:9002/order/create?productId11userId11222
4.8. 发起第三轮请求
把请求的地址调整成正确的路径再次请求测试 http://localhost:9002/order/create?productId1userId11222
终于有成功的了
4.9. 数据库数据验证
查看订单数据库是是否产生订单数据 从图中可以看出差生了一条订单数据 在查看扣库存数据是否也减少了呢 从上图可以看出产生一条订单数据就会减少一个库存符合咱们的预期分布式事务也生效了。
4.10. 发起第四轮请求
继续提高并发测试测试结果有的成功了有的失败了。
4.11. 数据库验证
产生了5条订单数据 相应的库存也减少了5个 测试验证到此为止