I am trying to implement a system of event sources using methods and principles in accordance with the various inspired examples of Greg Young that I saw.
I understand how the versioning logic works, and that when saving the aggregate, if the current version does not match the expected version, it means that another session / client application has updated the aggregate before you do it.
I also understand that you may have a method for retrospectively resolving conflicts while maintaining parallel events, this issue is not so much concerned.
What I'm trying to understand is that in a specific implementation using a nosql database such as ravendb as an event repository, how can I guarantee that the recorded events never overlap version numbers due to race conditions.
The following code is from an example project to illustrate:
There Repository<TAggregate>is a save method in the repository class
public void Save(AggregateRoot aggregate, int expectedVersion)
{
if (aggregate.GetUncommittedChanges().Any())
{
lock (_lockStorage)
{
var item = new T();
if (expectedVersion != -1)
{
item = GetById(aggregate.Id);
if (item.Version != expectedVersion)
{
throw new ConcurrencyException(string.Format("Aggregate {0} has been previously modified",
item.Id));
}
}
_storage.Save(aggregate);
}
}
}
Now essentially this works fine when there is only one application. A lock stops any other stream recording events in the event store, while the current thread takes a lock, checks the version, and then writes its own events.
, . , , GetById(), . . , .
, - , , .
, , Event Store. - , ? , ravendb , .