/// <summary>
 /// Commits pending transactions.
 /// </summary>
 /// <returns>A <see cref="Task"/>.</returns>
 public async Task Commit()
 {
     while (_pendingTransactions.Any())
     {
         using IWrappedTransaction transaction = _pendingTransactions.Dequeue();
         await transaction.CommitAsync().ConfigureAwait(false);
     }
 }
        /// <summary>
        /// Rolls back pending transactions.
        /// </summary>
        /// <returns>A <see cref="Task"/>.</returns>
        public Task Rollback()
        {
            while (_pendingTransactions.Any())
            {
                using IWrappedTransaction transaction = _pendingTransactions.Dequeue();
                transaction.Rollback();
            }

            return(Task.CompletedTask);
        }
        /// <summary>
        /// Stores one or more events for a given aggregate root.
        /// </summary>
        /// <param name="identifier">The aggregate root identifier.</param>
        /// <param name="expectedVersion">The expected version of the event stream of the aggregate root.</param>
        /// <param name="events">The events to store.</param>
        /// <param name="cancellationToken">A <see cref="CancellationToken"/>.</param>
        /// <returns>A <see cref="Task"/>.</returns>
        public async Task StoreEvents(TIdentifier identifier, long expectedVersion, IEnumerable <TEventBase> events, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            IWrappedTransaction transaction = await _createTransaction(_connection, identifier.ToString(), expectedVersion - 1).ConfigureAwait(false);

            _pendingTransactions.Enqueue(transaction);

            EventData[] eventData = events
                                    .Select(@event => new EventData(
                                                eventId: Guid.NewGuid(),
                                                type: @event.GetType().FullName,
                                                isJson: true,
                                                data: Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(@event, typeof(object), _jsonSerializerSettings)),
                                                metadata: Array.Empty <byte>()))
                                    .ToArray();

            cancellationToken.ThrowIfCancellationRequested();
            await transaction.WriteAsync(eventData).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();
        }