秒杀-订单创建消费者CreateOrderConsumer

这个类是基于MassTransit框架的消息消费者,负责接收 "库存扣减成功" 的消息并创建秒杀订单,同时通过消息通知库存服务确认订单状态。

复制代码
using MassTransit;
using MassTransit.Transports;
using SqlSugar;
using System.Transactions;
using ZR.Common.Model;
using ZR.Model.Stock;
using ZR.Service.Stock.IStockService;

/// <summary>
/// 订单创建消息消费者
/// 负责消费 CreateOrderMessage 消息,完成秒杀订单的创建
/// </summary>
public class CreateOrderConsumer : IConsumer<CreateOrderMessage>
{
    // 本地消息表服务(操作库存服务的消息记录)
    private readonly IStockMessageService _StockMessageService;
    // 秒杀订单服务(操作订单数据库)
    private readonly ISeckillOrderService _SeckillOrderService;
    // SqlSugar 数据库客户端(用于事务管理)
    private readonly ISqlSugarClient _SqlSugarClient;
    // MassTransit 消息总线(用于发送确认消息)
    private readonly IBus _bus;

    /// <summary>
    /// 构造函数注入依赖
    /// 通过依赖注入获取所需服务,解耦组件间依赖
    /// </summary>
    public CreateOrderConsumer(IStockMessageService stockMessageService, ISeckillOrderService seckillOrderService,
                                ISqlSugarClient sqlSugarClient, IBus bus)
    {
        _StockMessageService = stockMessageService;
        _SeckillOrderService = seckillOrderService;
        _SqlSugarClient = sqlSugarClient;
        _bus = bus;
    }

    /// <summary>
    /// 消费消息的核心方法
    /// 当 CreateOrderMessage 消息到达时自动调用
    /// </summary>
    public async Task Consume(ConsumeContext<CreateOrderMessage> context)
    {
        Console.WriteLine("_____________________CreateOrderConsumer____________");
        var message = context.Message; // 获取消息内容(订单号、商品ID、用户ID等)

        // 1. 幂等性检查:判断订单是否已存在(防止消息重复消费导致重复创建订单)
        var exist = await _SeckillOrderService.GetFirstAsync(x => x.OrderNo == message.OrderNo);
        if (exist != null)
        {
            // 订单已存在:直接发送"订单创建确认"消息,通知库存服务更新消息状态
            var uri = new Uri("exchange:stockConfirmQueue.direct?type=direct"); // 目标交换机地址
            var endPonit = await _bus.GetSendEndpoint(uri); // 获取消息发送端点
            if (endPonit == null)
                throw new Exception("消息创建失败");

            // 发送确认消息(包含订单号)
            await endPonit.Send(new ConfirmOrderCreatedMessage
            {
                OrderNo = message.OrderNo,
            }, ctx =>
            {
                ctx.SetRoutingKey("orderpublic"); // 指定路由键,匹配库存确认队列
            });
            return;
        }

        // 2. 订单不存在:创建新订单
        bool dbok = false; // 数据库事务是否成功
        string mess = "";  // 事务信息

        try
        {
            // 使用 SqlSugar 事务包装订单创建操作(确保原子性)
            (dbok, mess) = await _SqlSugarClient.UseTranAsync(async () =>
            {
                // 创建秒杀订单实体
                var order = new SeckillOrder
                {
                    OrderNo = message.OrderNo,   // 订单号(与库存服务生成的一致)
                    GoodsId = message.GoodsId,   // 商品ID
                    UserId = message.UserId,     // 用户ID
                    Status = "0",                // 订单状态(0-待支付)
                    CreateTime = DateTime.Now,   // 创建时间
                };
                // 保存订单到数据库
                _SeckillOrderService.Add(order);
            });

            // 3. 订单创建成功后,发送"订单创建确认"消息
            var uri = new Uri("exchange:stockConfirmQueue.direct?type=direct");
            var endPonit = await _bus.GetSendEndpoint(uri);
            if (endPonit == null)
                throw new Exception("消息创建失败");

            await endPonit.Send(new ConfirmOrderCreatedMessage
            {
                OrderNo = message.OrderNo,
            }, ctx =>
            {
                ctx.SetRoutingKey("orderpublic");
            });
        }
        catch (Exception ex)
        {
            // 异常时直接返回(依赖 MassTransit 重试机制重新消费消息)
            return;
        }
    }
}
相关推荐
开开心心就好3 分钟前
系统管理工具,多功能隐私清理文件粉碎工具
java·网络·windows·r语言·电脑·excel·symfony
少云清7 分钟前
【性能测试】3_性能测试基础 _指标
运维·服务器·数据库·性能测试·性能测试指标
+VX:Fegn08958 分钟前
计算机毕业设计|基于springboot + vue物流配送中心信息化管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·小程序·课程设计
逑之24 分钟前
C语言笔记15:动态内存管理
c语言·网络·笔记
hui函数31 分钟前
如何解决 pip install 网络报错 403 Forbidden(访问被阻止)问题
网络·pip
列御寇34 分钟前
MongoDB分片集群——集群组件概述
数据库·mongodb
乾元38 分钟前
现场运维机器人的工程化落地——移动探针采集 + AI 诊断,在真实网络中的实现路径
运维·网络·人工智能·架构·机器人·自动化
七夜zippoe40 分钟前
领域驱动设计在Python中的实现:从理论到生产级实践
数据库·python·sqlite·ddd·pydantic
小CC吃豆子41 分钟前
Qt的信号与槽机制
开发语言·数据库·qt
鲨莎分不晴43 分钟前
Docker 网络深度解析:打破容器的“孤岛效应”
网络·docker·容器