这个类是基于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;
}
}
}