要将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();
}
有更好的方法可以实现这一目标吗?