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); }
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(); } }
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); }