Exemplo n.º 1
0
        /// <inheritdoc />
        public async Task DeleteAggregateAsync <TIdentity, TAggregate>(
            TIdentity id,
            AggregateConfiguration <TIdentity, TAggregate> configuration,
            long expectedVersion,
            CancellationToken cancellationToken = default
            ) where TAggregate : Aggregate <TIdentity, TAggregate>
        {
            using var session = await _database.Client.StartSessionAsync(cancellationToken : cancellationToken);

            var stream = _streamNameResolver.Stream(id, configuration);

            session.StartTransaction();

            try
            {
                if (expectedVersion != ExpectedVersion.Any)
                {
                    var latestEvent = await _events
                                      .Find(session, e => e.Stream == stream)
                                      .SortByDescending(e => e.EventNumber)
                                      .FirstOrDefaultAsync(cancellationToken);

                    if (latestEvent == null)
                    {
                        if (expectedVersion != ExpectedVersion.NoStream)
                        {
                            throw ExpectedVersionValidation.ExpectedStreamToExist(stream, expectedVersion);
                        }
                    }
                    else if (expectedVersion != latestEvent.EventNumber)
                    {
                        throw ExpectedVersionValidation
                              .UnexpectedVersion(stream, expectedVersion, latestEvent.EventNumber);
                    }
                }

                await _events.DeleteManyAsync(session, e => e.Stream == stream, null, cancellationToken);

                await session.CommitTransactionAsync(cancellationToken);
            }
            catch (Exception)
            {
                // ReSharper disable once MethodSupportsCancellation
                await session.AbortTransactionAsync();

                throw;
            }
        }
Exemplo n.º 2
0
        /// <inheritdoc />
        public async Task AppendToStreamAsync <TIdentity, TAggregate>(
            TIdentity id,
            AggregateConfiguration <TIdentity, TAggregate> configuration,
            long expectedVersion,
            IEnumerable <IPendingEvent> pendingEvents,
            CancellationToken cancellationToken = default
            ) where TAggregate : Aggregate <TIdentity, TAggregate>
        {
            ExpectedVersionValidation.ValidateExpectedVersion(expectedVersion);

            var category = configuration.Name;
            var stream   = _streamNameResolver.Stream(id, configuration);

            using var session = await _events.Database.Client.StartSessionAsync(null, cancellationToken);

            session.StartTransaction(_transactionOptions);

            try
            {
                var latestEvent = await _events
                                  .Find(session, e => e.Stream == stream)
                                  .SortByDescending(e => e.EventNumber)
                                  .FirstOrDefaultAsync(cancellationToken);

                var currentVersion  = latestEvent?.EventNumber;
                var startingVersion = ExpectedVersionValidation
                                      .StartingVersion(expectedVersion, currentVersion, stream);

                var recordedEvents = pendingEvents
                                     .Select((pendingEvent, index) =>
                                             RecordedEvent(category, stream, pendingEvent, startingVersion + index)
                                             )
                                     .ToArray();

                try
                {
                    await _events.InsertManyAsync(session, recordedEvents, null, cancellationToken);

                    await session.CommitTransactionAsync(cancellationToken);
                }
                catch (MongoWriteException ex)
                {
                    if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey)
                    {
                        throw new WrongExpectedVersionException(
                                  "Either none or only a subset of the events were previously committed.",
                                  expectedVersion, currentVersion
                                  );
                    }

                    throw;
                }
            }
            catch (Exception)
            {
                // ReSharper disable once MethodSupportsCancellation
                await session.AbortTransactionAsync();

                throw;
            }
        }