











MediatR 的 Publish 方法默认是同步等待所有处理器执行完成的,
MediatR使用场景:
同步场景(必须等待结果):
数据验证
关键业务规则检查
使用 MediatR 的 Send 方法
CAP 事务消息原理
1. 开启数据库事务
2. 执行业务操作(创建订单)
3. 写入 CAP 消息到本地表(cap.published)
4. 提交事务
5. CAP 后台任务异步发送消息到 MQ
业务数据和消息记录在同一个数据库事务中,要么都成功,要么都失败。
CAP替代MediatR的场景,混合模式:
public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand, int> { public async Task<int> Handle(CreateOrderCommand request, CancellationToken ct) { using var transaction = await _dbContext.Database.BeginTransactionAsync(_capPublisher); try { // ===== 核心业务:写在一起,清晰可见 ===== // 1. 检查库存(核心,必须同步) var stock = await _inventoryService.CheckStockAsync(request.ProductName); if (stock < request.Quantity) throw new BusinessException("库存不足"); // 2. 计算价格(核心,必须同步) var price = await _pricingService.CalculateAsync(request); // 3. 创建订单(核心) var order = new Order { ProductName = request.ProductName, Quantity = request.Quantity, TotalPrice = price }; _dbContext.Orders.Add(order); // 4. 扣减库存(核心,必须在同一事务) await _inventoryService.DecreaseStockAsync(request.ProductName, request.Quantity); await _dbContext.SaveChangesAsync(ct); // ===== 非核心业务:通过 CAP 异步解耦 ===== // (邮件、短信、推送、统计等,失败了也不影响订单创建) await _capPublisher.PublishAsync("order.created", new { OrderId = order.Id, ProductName = order.ProductName, UserEmail = request.UserEmail }, cancellationToken: ct); await transaction.CommitAsync(ct); return order.Id; } catch { await transaction.RollbackAsync(ct); throw; } } } // 非核心业务通过 CAP 订阅处理 public class OrderEventSubscriber : ICapSubscribe { [CapSubscribe("order.created")] public async Task HandleOrderCreated(OrderCreatedEvent @event) { // 这些操作失败了不影响订单创建 await _emailService.SendAsync(@event.UserEmail, "订单创建成功"); await _smsService.SendAsync(@event.UserPhone, "订单创建成功"); await _statisticsService.UpdateAsync(@event.OrderId); } }
核心流程写在一起,一目了然;
非核心业务解耦
性能可控(异步不阻塞)
事务边界清晰
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。