public virtual async Task <IOperation?> CommitAsync(CancellationToken cancellationToken = default) { using var _ = await AsyncLock.LockAsync(cancellationToken).ConfigureAwait(false); if (IsCompleted) { throw Errors.TransactionScopeIsAlreadyClosed(); } try { if (!IsUsed) { return(null); } foreach (var dbContext in AllDbContexts) { if (!(dbContext.ChangeTracker.AutoDetectChangesEnabled || dbContext.ChangeTracker.HasChanges())) { continue; } await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false); } if (Command == null) { await Transaction !.CommitAsync(cancellationToken).ConfigureAwait(false); return(null); } else { var dbContext = PrimaryDbContext !.ReadWrite(); dbContext.ChangeTracker.Clear(); var operation = await DbOperationLog.AddAsync(dbContext, o => { o.StartTime = StartTime; o.CommitTime = Clock.Now; o.Command = Command; o.InvalidationData = InvalidationData; }, cancellationToken).ConfigureAwait(false); await Transaction !.CommitAsync(cancellationToken).ConfigureAwait(false); operation = await DbOperationLog.TryGetAsync(dbContext, operation.Id, cancellationToken); if (operation == null) { throw Errors.OperationCommitFailed(); } return(operation); } } finally { IsCompleted = true; } }
public virtual async Task <IOperation?> CommitAsync(CancellationToken cancellationToken = default) { using var _ = await AsyncLock.LockAsync(cancellationToken).ConfigureAwait(false); if (IsCompleted) { throw Errors.TransactionScopeIsAlreadyClosed(); } try { if (!IsUsed) { return(null); } if (Command == null) { await Transaction !.CommitAsync(cancellationToken).ConfigureAwait(false); return(null); } else { var dbContext = PrimaryDbContext !; var operation = await DbOperationLog.AddAsync(dbContext, o => { o.StartTime = StartTime; o.CommitTime = Clock.Now; o.Command = Command; o.Items = Items; }, cancellationToken).ConfigureAwait(false); await Transaction !.CommitAsync(cancellationToken).ConfigureAwait(false); operation = await DbOperationLog.TryGetAsync(dbContext, operation.Id, cancellationToken); if (operation == null) { throw Errors.OperationCommitFailed(); } return(operation); } } finally { IsCompleted = true; } }
public virtual async Task CommitAsync(CancellationToken cancellationToken = default) { using var _ = await AsyncLock.LockAsync(cancellationToken).ConfigureAwait(false); if (IsClosed) { throw Stl.Fusion.Operations.Internal.Errors.OperationScopeIsAlreadyClosed(); } try { if (!IsUsed) { IsConfirmed = true; return; } Operation.CommitTime = Clock.Now; if (Operation.Command == null) { throw Stl.Fusion.Operations.Internal.Errors.OperationHasNoCommand(); } var dbContext = DbContext !; dbContext.DisableChangeTracking(); // Just to speed up things a bit var operation = await DbOperationLog.AddAsync(dbContext, Operation, cancellationToken).ConfigureAwait(false); await Transaction !.CommitAsync(cancellationToken).ConfigureAwait(false); operation = await DbOperationLog.TryGetAsync(dbContext, operation.Id, cancellationToken); if (operation == null) { throw Errors.OperationCommitFailed(); } IsConfirmed = true; } finally { IsConfirmed ??= false; IsClosed = true; } }