private async Task ReleaseAsyncCore(IMessage message, Guid lockId, CancellationToken cancellationToken)
        {
            var transaction = await _dbContext.StartTransactionAsync(cancellationToken);

            try
            {
                var entity = await _dbContext.OutboxMessages
                             .FirstOrDefaultAsync(e =>
                                                  e.Id == message.Id &&
                                                  e.LockId == lockId,
                                                  cancellationToken)
                             .ConfigureAwait(false);

                if (entity is null)
                {
                    throw new ArgumentException($"message '{message.Id}' not found");
                }

                if (!entity.LockId.HasValue)
                {
                    throw new LockException($"message '{message.Id}' is not locked");
                }

                if (entity.LockId != lockId)
                {
                    throw new LockException($"invalid lock id '{lockId}' on message '{message.Id}'");
                }

                entity.LockId         = null;
                entity.LockTime       = null;
                entity.PublishingDate = DateTime.UtcNow;
                entity.Status         = MessageStatuses.Processed.ToString();
                await _dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

                await transaction.CommitAsync(cancellationToken);
            }
            catch
            {
                await transaction.RollbackAsync(cancellationToken);

                throw;
            }
        }
        public async Task <ITransaction> StartTransactionAsync(CancellationToken cancellationToken = default)
        {
            var transaction = await _dbContext.StartTransactionAsync(cancellationToken);

            return(transaction);
        }