Example #1
0
        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;
            }
        }
Example #2
0
        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;
            }
        }