Esempio n. 1
0
        public async Task <IReadOnlyCollection <ICommittedDomainEvent> > CommitEventsAsync(
            IIdentity id,
            IReadOnlyCollection <SerializedEvent> serializedEvents,
            CancellationToken cancellationToken)
        {
            if (!serializedEvents.Any())
            {
                return(new ICommittedDomainEvent[] {});
            }

            var eventDataModels = serializedEvents
                                  .Select((e, i) => new EventDataModel
            {
                AggregateId             = id.Value,
                AggregateName           = e.Metadata[MetadataKeys.AggregateName],
                BatchId                 = Guid.Parse(e.Metadata[MetadataKeys.BatchId]),
                Data                    = e.SerializedData,
                Metadata                = e.SerializedMetadata,
                AggregateSequenceNumber = e.AggregateSequenceNumber,
            })
                                  .ToList();

            _log.Verbose(
                "Committing {0} events to MSSQL event store for entity with ID '{1}'",
                eventDataModels.Count,
                id);

            const string sql = @"
                INSERT INTO
                    EventFlow
                        (BatchId, AggregateId, AggregateName, Data, Metadata, AggregateSequenceNumber)
                        OUTPUT CAST(INSERTED.GlobalSequenceNumber as bigint)
                    SELECT
                        BatchId, AggregateId, AggregateName, Data, Metadata, AggregateSequenceNumber
                    FROM
                        @rows
                    ORDER BY AggregateSequenceNumber ASC";

            IReadOnlyCollection <long> ids;

            try
            {
                ids = await _connection.InsertMultipleAsync <long, EventDataModel>(
                    Label.Named("mssql-insert-events"),
                    cancellationToken,
                    sql,
                    eventDataModels)
                      .ConfigureAwait(false);
            }
            catch (SqlException exception)
            {
                if (exception.Number == 2601)
                {
                    _log.Verbose(
                        "MSSQL event insert detected an optimistic concurrency exception for entity with ID '{0}'",
                        id);
                    throw new OptimisticConcurrencyException(exception.Message, exception);
                }

                throw;
            }

            eventDataModels = eventDataModels
                              .Zip(
                ids,
                (e, i) =>
            {
                e.GlobalSequenceNumber = i;
                return(e);
            })
                              .ToList();

            return(eventDataModels);
        }
Esempio n. 2
0
        protected override async Task <IReadOnlyCollection <ICommittedDomainEvent> > CommitEventsAsync <TAggregate>(string id, IReadOnlyCollection <SerializedEvent> serializedEvents, CancellationToken cancellationToken)
        {
            var batchId         = Guid.NewGuid();
            var aggregateType   = typeof(TAggregate);
            var aggregateName   = aggregateType.Name.Replace("Aggregate", string.Empty);
            var eventDataModels = serializedEvents
                                  .Select((e, i) => new EventDataModel
            {
                AggregateId             = id,
                AggregateName           = aggregateName,
                BatchId                 = batchId,
                Data                    = e.Data,
                Metadata                = e.Meta,
                AggregateSequenceNumber = e.AggregateSequenceNumber,
            })
                                  .ToList();

            Log.Verbose(
                "Committing {0} events to MSSQL event store for aggregate {1} with ID '{2}'",
                eventDataModels.Count,
                aggregateType.Name,
                id);

            const string sql = @"
                INSERT INTO
                    EventFlow
                        (BatchId, AggregateId, AggregateName, Data, Metadata, AggregateSequenceNumber)
                        OUTPUT CAST(INSERTED.GlobalSequenceNumber as bigint)
                    SELECT
                        BatchId, AggregateId, AggregateName, Data, Metadata, AggregateSequenceNumber
                    FROM
                        @rows";

            IReadOnlyCollection <long> ids;

            try
            {
                ids = await _connection.InsertMultipleAsync <long, EventDataModel>(
                    cancellationToken,
                    sql,
                    eventDataModels)
                      .ConfigureAwait(false);
            }
            catch (SqlException exception)
            {
                if (exception.Number == 2601)
                {
                    throw new OptimisticConcurrencyException(exception.Message, exception);
                }

                throw;
            }

            eventDataModels = eventDataModels
                              .Zip(
                ids,
                (e, i) =>
            {
                e.GlobalSequenceNumber = i;
                return(e);
            })
                              .ToList();

            return(eventDataModels);
        }