Лучший способ управлять оптимистичным параллелизмом для хранилища событий 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();
}
Есть лучший подход для достижения этого?