public async Task Rollback_ShouldRollbackAndDisposeAllPendingTransactions()
        {
            var wrappedTransactionMocks = new List <Mock <IWrappedTransaction> >();

            var createTransactionMock = new Mock <Func <IEventStoreConnection, string, long, Task <IWrappedTransaction> > >();

            createTransactionMock
            .Setup(x => x(_eventStoreConnectionMock.Object, "some_id", 0))
            .ReturnsAsync(() =>
            {
                var wrappedTransactionMock = new Mock <IWrappedTransaction>();
                wrappedTransactionMocks.Add(wrappedTransactionMock);
                return(wrappedTransactionMock.Object);
            });

            var transaction = new EventStoreTransaction <string, object>(
                connection: _eventStoreConnectionMock.Object,
                jsonSerializerSettings: _jsonSerializerSettings,
                createTransaction: createTransactionMock.Object);

            await transaction.StoreEvents("some_id", 1, new object[] { new EventA(), new EventB() });

            await transaction.StoreEvents("some_id", 1, new object[] { new EventA(), new EventB() });

            await transaction.StoreEvents("some_id", 1, new object[] { new EventA(), new EventB() });

            wrappedTransactionMocks.Should().HaveCount(3);
            wrappedTransactionMocks[0].Verify(x => x.Rollback(), Times.Never);
            wrappedTransactionMocks[1].Verify(x => x.Rollback(), Times.Never);
            wrappedTransactionMocks[2].Verify(x => x.Rollback(), Times.Never);

            await transaction.Rollback();

            wrappedTransactionMocks[0].Verify(x => x.CommitAsync(), Times.Never);
            wrappedTransactionMocks[1].Verify(x => x.CommitAsync(), Times.Never);
            wrappedTransactionMocks[2].Verify(x => x.CommitAsync(), Times.Never);

            wrappedTransactionMocks[0].Verify(x => x.Rollback(), Times.Once);
            wrappedTransactionMocks[1].Verify(x => x.Rollback(), Times.Once);
            wrappedTransactionMocks[2].Verify(x => x.Rollback(), Times.Once);

            wrappedTransactionMocks[0].Verify(x => x.Dispose(), Times.Once);
            wrappedTransactionMocks[1].Verify(x => x.Dispose(), Times.Once);
            wrappedTransactionMocks[2].Verify(x => x.Dispose(), Times.Once);

            // Dispose shouldn't have any side effect
            transaction.Dispose();

            wrappedTransactionMocks[0].Verify(x => x.CommitAsync(), Times.Never);
            wrappedTransactionMocks[1].Verify(x => x.CommitAsync(), Times.Never);
            wrappedTransactionMocks[2].Verify(x => x.CommitAsync(), Times.Never);

            wrappedTransactionMocks[0].Verify(x => x.Rollback(), Times.Once);
            wrappedTransactionMocks[1].Verify(x => x.Rollback(), Times.Once);
            wrappedTransactionMocks[2].Verify(x => x.Rollback(), Times.Once);

            wrappedTransactionMocks[0].Verify(x => x.Dispose(), Times.Once);
            wrappedTransactionMocks[1].Verify(x => x.Dispose(), Times.Once);
            wrappedTransactionMocks[2].Verify(x => x.Dispose(), Times.Once);
        }
Example #2
0
 private void ValidateAllEvent(IEnumerator <long> idEnumerator, IEnumerator <IDomainEvent <int> > evtEnumerator)
 {
     idEnumerator.MoveNext();
     evtEnumerator.MoveNext();
     try
     {
         do
         {
             var evt = evtEnumerator.Current;
             _tran.ValidateEvent(idEnumerator.Current, evt);
         } while (idEnumerator.MoveNext() && evtEnumerator.MoveNext());
         _tran.Commit();
     }
     catch
     {
         _tran.Rollback();
     }
 }
Example #3
0
        private async Task <long> DoWrite(string stream, IEnumerable <EventData> events, long?expectedVersion = null)
        {
            var bucket = Math.Abs(stream.GetHashCode() % _clients.Count());

            long nextVersion;

            using (var ctx = WriteTime.NewContext())
            {
                EventStoreTransaction transaction = null;
                try
                {
                    if (events.Count() > _readsize)
                    {
                        transaction = await _clients[bucket].StartTransactionAsync(stream, expectedVersion ?? ExpectedVersion.Any).ConfigureAwait(false);
                    }

                    if (transaction != null)
                    {
                        Logger.Write(LogLevel.Debug, () => $"Using transaction {events.Count()} is over max {_readsize} to write stream id [{stream}]");
                        var page = 0;
                        while (page < events.Count())
                        {
                            await transaction.WriteAsync(events.Skip(page).Take(_readsize)).ConfigureAwait(false);

                            page += _readsize;
                        }
                        var result = await transaction.CommitAsync().ConfigureAwait(false);

                        nextVersion = result.NextExpectedVersion;
                    }
                    else
                    {
                        var result = await
                                     _clients[bucket].AppendToStreamAsync(stream, expectedVersion ?? ExpectedVersion.Any, events)
                                     .ConfigureAwait(false);

                        nextVersion = result.NextExpectedVersion;
                    }
                }
                catch (WrongExpectedVersionException e)
                {
                    transaction?.Rollback();
                    throw new VersionException($"We expected version {expectedVersion ?? ExpectedVersion.Any}", e);
                }
                catch (CannotEstablishConnectionException e)
                {
                    transaction?.Rollback();
                    throw new PersistenceException(e.Message, e);
                }
                catch (OperationTimedOutException e)
                {
                    transaction?.Rollback();
                    throw new PersistenceException(e.Message, e);
                }
                catch (EventStoreConnectionException e)
                {
                    transaction?.Rollback();
                    throw new PersistenceException(e.Message, e);
                }

                WrittenEvents.Update(events.Count());
                WrittenEventsSize.Update(events.Sum(x => x.Data.Length));
                if (ctx.Elapsed > TimeSpan.FromSeconds(1))
                {
                    SlowLogger.Write(LogLevel.Warn, () => $"Writing {events.Count()} events of total size {events.Sum(x => x.Data.Length)} to stream [{stream}] version {expectedVersion} took {ctx.Elapsed.TotalSeconds} seconds!");
                }
                Logger.Write(LogLevel.Debug, () => $"Writing {events.Count()} events of total size {events.Sum(x => x.Data.Length)} to stream [{stream}] version {expectedVersion} took {ctx.Elapsed.TotalMilliseconds} ms");
            }
            return(nextVersion);
        }