# RocketMQ 实战:模拟电商网站场景综合案例(九)

RocketMQ 实战:模拟电商网站场景综合案例(九)

一、RocketMQ 实战:模拟电商网站场景综合案例-- 回退优惠券

1、回退优惠券


@Slf4j
@Component
@RocketMQMessageListener(topic = "${mq.order.topic}",consumerGroup = "${mq.order.consumer.group.name}",messageModel = MessageModel.BROADCASTING )
public class CancelMQListener implements RocketMQListener<MessageExt>{

    @Autowired
    private TradeCouponMapper couponMapper;

    @Override
    public void onMessage(MessageExt message) {

        try {
            //1. 解析消息内容
            String body = new String(message.getBody(), "UTF-8");
            MQEntity mqEntity = JSON.parseObject(body, MQEntity.class);
            log.info("接收到消息");
            //2. 查询优惠券信息
            TradeCoupon coupon = couponMapper.selectByPrimaryKey(mqEntity.getCouponId());
            //3.更改优惠券状态
            coupon.setUsedTime(null);
            coupon.setIsUsed(ShopCode.SHOP_COUPON_UNUSED.getCode());
            coupon.setOrderId(null);
            couponMapper.updateByPrimaryKey(coupon);
            log.info("回退优惠券成功");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("回退优惠券失败");
        }
    }
}

2、在 shop-coupon-service 工程模块中,完成 消费消息的 监听类 CancelMQListener.java 代码实现。


/**
 *   shop\shop-coupon-service\src\main\java\com\itheima\shop\mq\CancelMQListener.java
 *
 *   2024-6-11 创建 消费消息的 监听类 CancelMQListener.java
 */
package com.itheima.shop.mq;

import com.alibaba.fastjson.JSON;
import com.itheima.constant.ShopCode;
import com.itheima.entity.MQEntity;
import com.itheima.shop.mapper.TradeCouponMapper;
import com.itheima.shop.pojo.TradeCoupon;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;

@Slf4j
@Component
@RocketMQMessageListener(topic = "${mq.order.topic}", consumerGroup = "${mq.order.consumer.group.name}", messageModel = MessageModel.BROADCASTING)
public class CancelMQListener implements RocketMQListener<MessageExt> {

    @Autowired
    private TradeCouponMapper couponMapper;

    @Override
    public void onMessage(MessageExt message) {

        try {
            //1. 解析消息内容
            String body = new String(message.getBody(), "UTF-8");
            MQEntity mqEntity = JSON.parseObject(body, MQEntity.class);
            log.info("接收到消息");
            if(mqEntity.getCouponId()!=null){
                //2. 查询优惠券信息
                TradeCoupon coupon = couponMapper.selectByPrimaryKey(mqEntity.getCouponId());
                //3.更改优惠券状态
                coupon.setUsedTime(null);
                coupon.setIsUsed(ShopCode.SHOP_COUPON_UNUSED.getCode());
                coupon.setOrderId(null);
                couponMapper.updateByPrimaryKey(coupon);
            }
            log.info("回退优惠券成功");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("回退优惠券失败");
        }
    }
}

二、RocketMQ 实战:模拟电商网站场景综合案例-- 回退用户余额

1、回退用户余额


@Slf4j
@Component
@RocketMQMessageListener(topic = "${mq.order.topic}",consumerGroup = "${mq.order.consumer.group.name}",messageModel = MessageModel.BROADCASTING )
public class CancelMQListener implements RocketMQListener<MessageExt>{

    @Autowired
    private IUserService userService;

    @Override
    public void onMessage(MessageExt messageExt) {

        try {
            //1.解析消息
            String body = new String(messageExt.getBody(), "UTF-8");
            MQEntity mqEntity = JSON.parseObject(body, MQEntity.class);
            log.info("接收到消息");
            if(mqEntity.getUserMoney()!=null && mqEntity.getUserMoney().compareTo(BigDecimal.ZERO)>0){
                //2.调用业务层,进行余额修改
                TradeUserMoneyLog userMoneyLog = new TradeUserMoneyLog();
                userMoneyLog.setUseMoney(mqEntity.getUserMoney());
                userMoneyLog.setMoneyLogType(ShopCode.SHOP_USER_MONEY_REFUND.getCode());
                userMoneyLog.setUserId(mqEntity.getUserId());
                userMoneyLog.setOrderId(mqEntity.getOrderId());
                userService.updateMoneyPaid(userMoneyLog);
                log.info("余额回退成功");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("余额回退失败");
        }
    }
}

2、在 shop-user-service 工程模块中,完成 消费消息的 监听类 CancelMQListener.java 代码实现。


/**
 *   shop\shop-user-service\src\main\java\com\itheima\shop\mq\CancelMQListener.java
 *
 *   2024-6-11 创建 消费消息的 监听类 CancelMQListener.java
 */
package com.itheima.shop.mq;

import com.alibaba.fastjson.JSON;
import com.itheima.api.IUserService;
import com.itheima.constant.ShopCode;
import com.itheima.entity.MQEntity;
import com.itheima.shop.pojo.TradeUserMoneyLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;

@Slf4j
@Component
@RocketMQMessageListener(topic = "${mq.order.topic}",consumerGroup = "${mq.order.consumer.group.name}",messageModel = MessageModel.BROADCASTING )
public class CancelMQListener implements RocketMQListener<MessageExt>{

    @Autowired
    private IUserService userService;

    @Override  //用户余额回退
    public void onMessage(MessageExt messageExt) {

        try {
            //1.解析消息
            String body = new String(messageExt.getBody(), "UTF-8");
            MQEntity mqEntity = JSON.parseObject(body, MQEntity.class);
            log.info("接收到消息");
            if(mqEntity.getUserMoney()!=null && mqEntity.getUserMoney().compareTo(BigDecimal.ZERO)>0){
                //2.调用业务层,进行余额修改
                TradeUserMoneyLog userMoneyLog = new TradeUserMoneyLog();
                userMoneyLog.setUseMoney(mqEntity.getUserMoney());
                userMoneyLog.setMoneyLogType(ShopCode.SHOP_USER_MONEY_REFUND.getCode());
                userMoneyLog.setUserId(mqEntity.getUserId());
                userMoneyLog.setOrderId(mqEntity.getOrderId());
                userService.updateMoneyPaid(userMoneyLog);
                log.info("余额回退成功");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("余额回退失败");
        }
    }
}

三、RocketMQ 实战:模拟电商网站场景综合案例-- 取消订单

1、取消订单


@Override
    public void onMessage(MessageExt messageExt) {
        String body = new String(messageExt.getBody(), "UTF-8");
        String msgId = messageExt.getMsgId();
        String tags = messageExt.getTags();
        String keys = messageExt.getKeys();
        log.info("CancelOrderProcessor receive message:"+messageExt);
        CancelOrderMQ cancelOrderMQ = JSON.parseObject(body, CancelOrderMQ.class);
        TradeOrder order = orderService.findOne(cancelOrderMQ.getOrderId());
		order.setOrderStatus(ShopCode.SHOP_ORDER_CANCEL.getCode());
        orderService.changeOrderStatus(order);
        log.info("订单:["+order.getOrderId()+"]状态设置为取消");
        return order;
    }

2、在 shop-order-service 工程模块中,完成 消费消息的 监听类 CancelMQListener.java 代码实现。


/**
 *   shop\shop-order-service\src\main\java\com\itheima\shop\mq\CancelMQListener.java
 *
 *   2024-6-11 创建 消费消息的 监听类 CancelMQListener.java
 */
package com.itheima.shop.mq;

import com.alibaba.fastjson.JSON;
import com.itheima.constant.ShopCode;
import com.itheima.entity.MQEntity;
import com.itheima.shop.mapper.TradeOrderMapper;
import com.itheima.shop.pojo.TradeOrder;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;

@Slf4j
@Component
@RocketMQMessageListener(topic = "${mq.order.topic}",consumerGroup = "${mq.order.consumer.group.name}",messageModel = MessageModel.BROADCASTING )
public class CancelMQListener implements RocketMQListener<MessageExt>{

    @Autowired
    private TradeOrderMapper orderMapper;

    @Override  //取消订单
    public void onMessage(MessageExt messageExt) {

        try {
            //1. 解析消息内容
            String body = new String(messageExt.getBody(),"UTF-8");
            MQEntity mqEntity = JSON.parseObject(body, MQEntity.class);
            log.info("接受消息成功");
            //2. 查询订单
            TradeOrder order = orderMapper.selectByPrimaryKey(mqEntity.getOrderId());
            //3.更新订单状态为取消
            order.setOrderStatus(ShopCode.SHOP_ORDER_CANCEL.getCode());
            orderMapper.updateByPrimaryKey(order);
            log.info("订单状态设置为取消");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.info("订单取消失败");
        }
    }
}

四、RocketMQ 实战:模拟电商网站场景综合案例-- 失败补偿机制测试

1 、测试流程

1)准备测试环境

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ShopOrderServiceApplication.class)
public class OrderTest {

    @Autowired
    private IOrderService orderService;
}
2)准备测试数据
  • 用户数据
  • 商品数据
  • 优惠券数据
3)测试下单成功流程

@Test    
public void add(){
    Long goodsId=XXXL;
    Long userId=XXXL;
    Long couponId=XXXL;

    TradeOrder order = new TradeOrder();
    order.setGoodsId(goodsId);
    order.setUserId(userId);
    order.setGoodsNumber(1);
    order.setAddress("北京");
    order.setGoodsPrice(new BigDecimal("5000"));
    order.setOrderAmount(new BigDecimal("5000"));
    order.setMoneyPaid(new BigDecimal("100"));
    order.setCouponId(couponId);
    order.setShippingFee(new BigDecimal(0));
    orderService.confirmOrder(order);
}

执行完毕后,查看数据库中用户的余额、优惠券数据,及订单的状态数据

4)测试下单失败流程

代码同上。

执行完毕后,查看用户的余额、优惠券数据是否发生更改,订单的状态是否为取消。

2、删除数据库中使用日志表 和 记录表 内容,即 删除以下数据表内容。

trade_goods_number_log
trade_mq_consumer_log
trade_order
trade_user_money_log

3、保证 数据库中,用户 商品 优惠券 数据。

trade_user 表中,有数据,如余额是 1000 。
trade_order 表中,无数据。
trade_conpon 表中,优惠券 状态为 0 可用,优惠券 20 。

4、在 shop-order-service 工程模块中,创建 测试类 OrderServiceTest.java


/**
 *   shop\shop-order-service\src\test\java\com\itheima\test\OrderServiceTest.java
 *
 *   2024-6-11 创建 测试类 OrderServiceTest.java
 */
package com.itheima.test;

import com.itheima.api.IOrderService;
import com.itheima.shop.OrderServiceApplication;
import com.itheima.shop.pojo.TradeOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.math.BigDecimal;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = OrderServiceApplication.class)
public class OrderServiceTest {

    @Autowired
    private IOrderService orderService;

    @Test
    public void confirmOrder() throws IOException {

        Long coupouId = 345988230098857984L;
        Long goodsId = 345959443973935104L;
        Long userId = 345963634385633280L;

        TradeOrder order = new TradeOrder();
        order.setGoodsId(goodsId);
        order.setUserId(userId);
        order.setCouponId(coupouId);
        order.setAddress("北京");
        order.setGoodsNumber(1);
        order.setGoodsPrice(new BigDecimal(1000));
        order.setShippingFee(BigDecimal.ZERO);
        order.setOrderAmount(new BigDecimal(1000));
        order.setMoneyPaid(new BigDecimal(100));
        orderService.confirmOrder(order);

        System.in.read();
    }
}

5、启动测试类,查看数据库变化 和 idea 日志输出。

# RocketMQ 实战:模拟电商网站场景综合案例(八)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型QA

Q:关于 Yi-9B 通过 input/output cosine 来分析模型,可能文档里没有把前提说明白。该指标确实存在你们提到的不同模型大小不可比的问题。所以我们比较的是同一个模型在不同训练阶段,以及 layer 深度相同的dense models 之间的比较。除了发现yi-6B/34B 随着训练 tokens 的增加…

在矩池云使用GLM-4的详细指南(无感连GitHubHuggingFace)

GLM-4-9B 是智谱 AI 推出的最新一代预训练模型 GLM-4 系列中的开源版本&#xff0c;在多项测试中表现出超越已有同等规模开源模型的性能&#xff0c;它能兼顾多轮对话、网页浏览、代码执行、多语言、长文本推理等多种功能&#xff0c;性能更加强大。其多模态语言模型GLM-4V-9B在…

Autohotkey使用记录

文章目录 1. 安装1.1 autohotkey1.2 vscode需要安装的插件 3. 函数使用3.1 按键3.2 MouseMove 4. Bug分析4.1 A_TimeSincePriorHotkey 1. 安装 1.1 autohotkey 下载安装即可 1.2 vscode需要安装的插件 3. 函数使用 3.1 按键 各个按键的代词使用关键字搜索&#xff1a;Hotk…

antd Pagination分页组件自定义跳转文案、按钮的方法【配置组件自带api即可支持】

组件默认效果&#xff1a; 期望效果&#xff1a; 代码&#xff1a; <PaginationclassNamelist-pagerpageSize{10}current{params?.pageNo}responsivetotal{listData?.totalItem}showSizeChanger{false}showQuickJumper{{ goButton: <Button classNamego-page>确定…

一、时钟控制

时钟 STM32F4有五种时钟源 HSI 内部高速时钟LSI 内部低速时钟HSE 外部高速时钟LSE 外部低速时钟PLL 锁相环倍频输出 其中 HSI、HSE、PLL可驱动系统时钟 (SYSCLK)&#xff0c;对于每个时钟源来说&#xff0c;在未使用时都可单独打开或者关闭&#xff0c;以降低功耗。 HSE高速…

计算机信息安全技术课后习题答案

计算机信息安全技术课后习题答案 计算机信息安全技术&#xff08;第2版&#xff09;付永刚 部分习题答案 第一章 计算机信息安全技术概述 选择题 关于访问控制服务的描述中&#xff0c;正确的是&#xff08; A &#xff09; A. 可控制用户访问网络资源 B.可识别发送方的真实身…

多用户竞拍商城系统 挂售转卖竞拍商城系统源码 竞拍系统 竞拍系统开发定制 转拍闪拍系统 后端PHP+前端UNIAPP源码+教程

挂售转卖竞拍商城系统源码/竞拍系统/转拍闪拍系统/后端PHP前端UNIAPP源码 玩法简介 ①、后台可添加商品进行挂单 ②、后台设置场次以及场次开始时间 ③、用户抢单 ④、抢单以后可选择提货或者转售 ⑤、玩家寄售需按照后台设置百分比进行加价 ⑥、玩家寄售需支付手续费(余额支付…

u盘数据要在哪台电脑上恢复?u盘数据恢复后保存在哪里

在数字化时代&#xff0c;U盘已成为我们日常生活中不可或缺的数据存储设备。然而&#xff0c;由于各种原因&#xff0c;U盘中的数据可能会意外丢失&#xff0c;这时数据恢复就显得尤为重要。但是&#xff0c;很多人对于在哪台电脑上进行U盘数据恢复以及恢复后的数据应保存在哪里…

【Ardiuno】实验ESP32单片机完成搭建简易Web服务器功能(图文)

今天&#xff0c;小飞鱼继续来测试使用ESP32来实现简易的wifi无线web服务器功能。使用Ardiuno平台编辑器输入以下示例代码&#xff1a; #include <WiFi.h> #include <WiFiClient.h> #include <WebServer.h> #include <ESPmDNS.h>const char* ssid &q…

【UE5|水文章】在UMG上显示帧率

参考视频&#xff1a; https://www.youtube.com/watch?vH_NdvImlI68 蓝图&#xff1a;

50.Python-web框架-Django中引入静态的bootstrap样式

目录 Bootstrap 官网 特性 下载 在线样例 Bootstrap 入门 Bootstrap v5 中文文档 v5.3 | Bootstrap 中文网 在django中使用bootstrap 新建static\bootstrap5目录&#xff0c;解压后的Bootstrap文件&#xff0c;拷贝项目里就好。 在template文件里引用css文…

全华人团队推出多模态大模型新基准,GPT-4o准确率仅为65.5%,所有模型最易犯感知错误

GPT-4o再次掀起多模态大模型的浪潮。 如果他们能以近似人类的熟练程度&#xff0c;在不同领域执行广泛的任务&#xff0c;这对许多领域带来革命性进展。 因而&#xff0c;构建一个全面的评估基准测试就显得格外重要。然而评估大型视觉语言模型能力的进程显著落后于它们自身的…

Windows7及以上系统中管理员权限与UAC虚拟化详解(附源码)

目录 1、管理员权限 2、UAC虚拟化 3、将程序配置为以管理员权限启动 4、判断程序有没有管理员权限 5、以管理员权限启动目标程序 6、开机自启动程序不能设置管理员权限 VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/art…

Samtec技术前沿 | 高达128 GT/s :全新概念验证型高速电缆解决方案性能

【摘要/前言】 即将发布的PCIe 7.0 规范旨在实现128 GT/s的数据传输速率。它延续了PCIe 每一代产品速度翻番的趋势。根据 PCI-SIG的说法&#xff0c;"PCIe 7.0 技术的目标是为人工智能/机器学习、数据中心、高性能计算、汽车和物联网等数据密集型市场提供可扩展的互连解决…

Docker笔记-Debian容器内搭建ssh服务

登陆容器之后修改密码&#xff1a; passwd 密码设置完成后安装openssh-server apt-get install openssh-server 修改端口号为50022并添加配置 vim /etc/ssh/sshd_config 修改成 Port 50022 PasswordAuthentication yes PermitRootLogin yes 启动 rootlinux:~# /etc/in…

实现AI口语练习的技术库

国内实现AI口语练习的第三方技术库比较多&#xff0c;以下是一些国内实现AI口语练习的第三方技术库。开发人员可以根据自己的需求选择合适的技术库进行开发。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 讯飞开放平台&#xff1a; …

2024世界人工智能大会“SAIL奖”发布

作为世界人工智能大会的最高奖项&#xff0c;SAIL 奖&#xff08;Super AI Leader&#xff0c;卓越人工智能引领者&#xff09;坚持“追求卓越、引领未来”的理念&#xff0c;评选和运营秉持“高端化、国际化、专业化、市场化、智能化”原则&#xff0c;从全球范围发掘在人工智…

【SpringBoot+Vue】后端代码使用Mybatis实现自动生成实体类的功能

参考】 SpringBoot多环境配置详解(application-dev.yml、application-test.yml、application-prod.yml) springboot集成mybatis【使用generatorConfig.xml配置自动生成代码】 怎么快速查看自己mysql的安装位置 解决 http://mybatis.org/dtd/mybatis-generator-config_1_0.dt…

Source Insight 4.0软件使用记录

目录 工程创建 个人使用 Source Insight 4.0 软件的一些记录。 工程创建 建议起名和自己工程名相同&#xff0c;不能有中文&#xff0c;否则一定会出错 这一步直接点ok即可&#xff1a; 添加所有文件 勾上&#xff1a; 随后便可在右边&#xff0c;打开文件进行阅读

美国公司狂招AI人才!AI产品经理年薪近百万美元,众多中高级职位空缺

据《华尔街日报》报道&#xff0c;美国以娱乐和制造业为主的公司正在掀起一场AI招聘狂潮&#xff0c;广招数据科学家、机器学习专家及其他擅长部署AI技术的从业人员。 由于AI从业人员供不应求&#xff0c;中高级职位大量空缺&#xff0c;许多公司开出六位数以上的薪水&#xf…