.net core 项目 分布式事物 如果 中间某个环节 出现 异常他是如何解决的

cap 分布式事物框架  .net core 项目 分布式事物 如果 中间某个环节 出现 异常他是如何解决的 请用代码 解释说明

在.NET Core项目中,使用 ‌CAP 框架‌ 处理分布式事务中间环节异常时,主要通过 ‌消息持久化 + 重试机制 + 补偿事务‌ 
保证最终一致性。以下用代码示例说明关键处理逻辑: 一、环境配置(Startup.cs) csharp Copy Code
public void ConfigureServices(IServiceCollection services) { // 配置CAP(使用SQL Server存储 + RabbitMQ消息队列) services.AddCap(config => { config.UseSqlServer(Configuration.GetConnectionString("Default")); // 事务日志存储 config.UseRabbitMQ(options => { options.HostName = "localhost"; options.Port = 5672; }); config.FailedRetryCount = 3; // 失败重试次数 config.FailedRetryInterval = 60; // 重试间隔(秒) }); } 二、发布事件(聚合根或应用服务) csharp Copy Code public class OrderService { private readonly ICapPublisher _capPublisher; private readonly AppDbContext _dbContext; public OrderService(ICapPublisher capPublisher, AppDbContext dbContext) { _capPublisher = capPublisher; _dbContext = dbContext; } [Transaction] // 开启事务(确保业务操作与事件发布原子性) public async Task CreateOrder(Order order) { // 1. 业务操作:保存订单 _dbContext.Orders.Add(order); await _dbContext.SaveChangesAsync(); // 2. 发布领域事件(与数据库操作在同一事务中) await _capPublisher.PublishAsync("Order.Created", new OrderCreatedEvent(order.Id, order.Amount)); } } 三、订阅事件处理(消费者服务) csharp Copy Code public class InventorySubscriber : ICapSubscribe { private readonly AppDbContext _dbContext; public InventorySubscriber(AppDbContext dbContext) { _dbContext = dbContext; } [CapSubscribe("Order.Created")] // 订阅订单创建事件 public async Task HandleOrderCreated(OrderCreatedEvent @event) { try { // 1. 扣减库存 var inventory = await _dbContext.Inventories .FirstAsync(i => i.ProductId == @event.ProductId); if (inventory.Stock < @event.Amount) throw new InsufficientStockException("库存不足"); // 显式抛出业务异常 inventory.Stock -= @event.Amount; await _dbContext.SaveChangesAsync(); } catch (Exception ex) { // 记录异常日志(含重试次数) var retryAttempt = Context.GetRetryAttempt(); Log.Error($"库存扣减失败,重试次数:{retryAttempt}, 异常:{ex}"); throw; // 抛出异常触发CAP重试 } } } 四、异常处理机制 自动重试‌ 当HandleOrderCreated抛出异常时,CAP根据FailedRetryCount和FailedRetryInterval自动重试。 重试次数通过Context.GetRetryAttempt()获取,可用于日志或条件判断。 最终失败补偿‌ csharp Copy Code // 补偿方法(需手动调用) [HttpPost("inventory/compensate")] public async Task CompensateInventory(Guid orderId) { // 根据订单ID回滚库存(人工介入或自动化补偿) var order = await _dbContext.Orders.FindAsync(orderId); var inventory = await _dbContext.Inventories.FindAsync(order.ProductId); inventory.Stock += order.Amount; await _dbContext.SaveChangesAsync(); } 当重试次数耗尽后,消息进入 ‌“Failed” 死信队列‌,需人工或自动触发补偿。 五、关键设计说明 机制‌ ‌CAP实现方式‌ 事务一致性‌ 本地数据库事务与消息发布通过[Transaction]属性绑定,确保原子性 消息可靠性‌ 事件持久化到数据库,消息队列确认后才标记为成功,避免消息丢失 异常隔离性‌ 消费者异常不会影响发布者事务,通过异步重试保证最终一致性 监控与补偿‌ CAP Dashboard可视化查看失败消息,支持手动重试或触发补偿接口 总结 通过 CAP 框架的 ‌事务消息表 + 自动重试 + 死信队列‌ 机制,分布式事务中间环节异常的处理流程为: 自动重试‌:瞬时错误(如网络抖动)通过重试恢复; 人工干预‌:持久性错误(如库存不足)需补偿或业务修正; 最终一致‌:确保所有参与服务最终达成一致状态。

 

posted on 2025-04-27 17:10  是水饺不是水饺  阅读(23)  评论(0)    收藏  举报

导航