public async Task AppendExclusive(string streamKey, CancellationToken token, params object[] events) { _store.Events.EnsureAsStringStorage(_session); var cmd = new NpgsqlCommand($"select version from {_store.Events.DatabaseSchemaName}.mt_streams where id = :id for update") .With("id", streamKey); await _session.BeginTransactionAsync(token).ConfigureAwait(false); var version = await readVersionFromExistingStream(streamKey, token, cmd).ConfigureAwait(false); var action = Append(streamKey, events); action.ExpectedVersionOnServer = version; }
public async Task <IEventStream <TDoc> > FetchForWriting(DocumentSessionBase session, TId id, bool forUpdate, CancellationToken cancellation = default) { var selector = await _identityStrategy.EnsureAggregateStorageExists <TDoc>(session, cancellation).ConfigureAwait(false); if (forUpdate) { await session.BeginTransactionAsync(cancellation).ConfigureAwait(false); } var command = _identityStrategy.BuildCommandForReadingVersionForStream(id, forUpdate); var builder = new CommandBuilder(command); builder.Append(";"); var handler = _identityStrategy.BuildEventQueryHandler(id, selector); handler.ConfigureCommand(builder, session); long version = 0; try { using var reader = await session.ExecuteReaderAsync(builder.Compile(), cancellation).ConfigureAwait(false); if (await reader.ReadAsync(cancellation).ConfigureAwait(false)) { version = await reader.GetFieldValueAsync <long>(0, cancellation).ConfigureAwait(false); } await reader.NextResultAsync(cancellation).ConfigureAwait(false); var events = await handler.HandleAsync(reader, session, cancellation).ConfigureAwait(false); var document = await _aggregator.BuildAsync(events, session, default, cancellation).ConfigureAwait(false);
public async Task <IEventStream <TDoc> > FetchForWriting(DocumentSessionBase session, TId id, bool forUpdate, CancellationToken cancellation = default) { await _identityStrategy.EnsureAggregateStorageExists <TDoc>(session, cancellation).ConfigureAwait(false); await session.Database.EnsureStorageExistsAsync(typeof(TDoc), cancellation).ConfigureAwait(false); if (forUpdate) { await session.BeginTransactionAsync(cancellation).ConfigureAwait(false); } var command = _identityStrategy.BuildCommandForReadingVersionForStream(id, forUpdate); var builder = new CommandBuilder(command); builder.Append(";"); var handler = new LoadByIdHandler <TDoc, TId>(_storage, id); handler.ConfigureCommand(builder, session); long version = 0; try { using var reader = await session.ExecuteReaderAsync(builder.Compile(), cancellation).ConfigureAwait(false); if (await reader.ReadAsync(cancellation).ConfigureAwait(false)) { version = await reader.GetFieldValueAsync <long>(0, cancellation).ConfigureAwait(false); } await reader.NextResultAsync(cancellation).ConfigureAwait(false); var document = await handler.HandleAsync(reader, session, cancellation).ConfigureAwait(false); return(version == 0 ? _identityStrategy.StartStream <TDoc>(document, session, id, cancellation) : _identityStrategy.AppendToStream <TDoc>(document, session, id, version, cancellation)); } catch (Exception e) { if (e.Message.Contains(MartenCommandException.MaybeLockedRowsMessage)) { throw new StreamLockedException(id, e.InnerException); } throw; } }