public void Store(Guid aggregateId, long aggregateVersion, EventBase[] events) { var currentVersion = aggregateVersion; var expectedInitialVersion = currentVersion - events.Count(); var streamId = aggregateId; var connectionString = _dataAccessConfiguration.EventStoreConnectionString; var serializedEvents = events.Select(x => new Tuple<string, string>( x.GetType().FullName + "," + x.GetType().Assembly.GetName(), JsonConvert.SerializeObject(x, _serializerSettings))); using (var t = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Serializable })) { using (var con = new SqlConnection(connectionString)) { con.Open(); const string commandText = "SELECT TOP 1 CurrentSequence " + "FROM Streams WITH (UPDLOCK) WHERE StreamId = @StreamId;"; long? existingSequence; using (var command = new SqlCommand(commandText, con)) { command.Parameters.AddWithValue("StreamId", streamId); var current = command.ExecuteScalar(); existingSequence = current == null ? (long?)null : (long)current; if (existingSequence != null && ((long)existingSequence) != expectedInitialVersion) throw new ConcurrencyException(); } var nextVersion = InsertEventsAndReturnLastVersion(streamId, con, expectedInitialVersion, serializedEvents); if (existingSequence == null) StartNewSequence(streamId, nextVersion, con); else UpdateSequence(streamId, expectedInitialVersion, nextVersion, con); t.Complete(); } } _bus.Publish(events); }