using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Fake.UnitOfWork; namespace Oms.Application.Messaging; /// /// 把创单/预报之后的副作用延后到当前事务提交成功再执行,每一步单独提交。 /// internal static class OmsAfterCommit { public static Task ScheduleAsync(IUnitOfWorkManager unitOfWorkManager, Func action) { var current = unitOfWorkManager.Current; if (current != null && !current.IsCompleted) { // OnCompleted 仍处在创单事务里,此时再写 Outbox 征用不到连接,事件会丢。 // 等工作单元释放后再开独立事务。 EventHandler handler = null!; handler = (_, _) => { current.Disposed -= handler; _ = Task.Run(action); }; current.Disposed += handler; return Task.CompletedTask; } return action(); } /// /// 新开独立事务执行一步。失败只记日志,不抛回调用方。 /// public static async Task RunStepAsync( IServiceScopeFactory scopeFactory, ILogger logger, string step, Func work) { try { using var scope = scopeFactory.CreateScope(); var unitOfWorkManager = scope.ServiceProvider.GetRequiredService(); using var unitOfWork = unitOfWorkManager.Begin(OmsOutboxUnitOfWork.Independent()); await OmsIntegrationEventPublisher.EnsureOutboxDbContextAsync(unitOfWorkManager); await work(scope.ServiceProvider); await unitOfWork.CompleteAsync(); return true; } catch (Exception ex) { logger.LogError(ex, "订单后置步骤失败 Step={Step}", step); return false; } } }