Лучший способ управлять оптимистичным параллелизмом для хранилища событий mongoDb

Чтобы использовать MongoDB в качестве хранилища событий, мне было интересно, как правильно решить проблему с хранением событий и обеспечить их последовательный порядок в хранилище.

Я принял оптимистический подход к параллельному назначению номера "Версия" для события. Я установил это поле как уникальный индекс в коллекции mongo, чтобы избежать одновременной работы двух клиентов при сохранении одной и той же версии события.

Исключение параллелизма должно обрабатываться обработчиком приложения MongoCommandException.

    public async Task AppendEventsToStreamAsync(string streamName, IEnumerable<DomainEvent> domainEvents, int expectedVersion)
    {
        var events = domainEvents as DomainEvent[] ?? domainEvents.ToArray();

        if (!events.Any())
        {
            throw new Exception($"Stream {streamName} is empty");
        }

        _sessionHandle.StartTransaction();

        var collection = _database.GetCollection<StoredDomainEvent>(streamName);

        // Ensure Version will be unique to manage optimistic concurrency on the event stream
        await collection.Indexes.CreateOneAsync(
            new CreateIndexModel<StoredDomainEvent>(new JsonIndexKeysDefinition<StoredDomainEvent>(
                "{Version:1}"),
                new CreateIndexOptions
                {
                    Unique = true
                }));

        var enumerable = events.Select(evt => evt.ToStorablePoco()).ToList();

        foreach (var evt in enumerable)
        {
            evt.Id = Guid.NewGuid().ToString();
            evt.Version = expectedVersion++;
        }

        // Append the events to the store
        await collection.InsertManyAsync(_sessionHandle, enumerable);

        await _sessionHandle.CommitTransactionAsync();
    }

Есть лучший подход для достижения этого?

0 ответов

Другие вопросы по тегам