Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AggregateRoot version never updated #7

Open
xdeclercq opened this issue Feb 19, 2015 · 9 comments
Open

AggregateRoot version never updated #7

xdeclercq opened this issue Feb 19, 2015 · 9 comments

Comments

@xdeclercq
Copy link

It loos like the AggregateRoot Version field is never updated. It should probably be updated at the end of the LoadsFromHistory method (which should probably be renamed LoadFromHistory), with the version of the last event replayed.

@beachwalker
Copy link

This should be incremented when applying any change to the AggregateRoot, so from my point of view the method LoadFromHistory() is not the right point for incrementing the version field. You should do this here instead:

private void ApplyChange(Event @event, bool isNew)
{
    this.AsDynamic().Apply(@event);
    if(isNew) _changes.Add(@event);
    this.Version++
}

(Greg may hit me if I'm wrong)

@Narvalex
Copy link

Narvalex commented Dec 2, 2015

That's correct, @beachwalker! You are not wrong :)

@xdeclercq
Copy link
Author

Indeed.

beachwalker added a commit to beachwalker/m-r that referenced this issue Dec 2, 2015
The version of the AggregateRoot gets incremented whenever a new event
is applied.
@amolenk
Copy link

amolenk commented Dec 13, 2015

I'd say that the version should be updated at two different points:

  1. Aggregate is rehydrated, Version should reflect the current version number. This could be done in LoadFromHistory method.
  2. When the changes are committed (MarkChangesAsCommitted method).

I wouldn't increase the version number directly after an event is applied and the aggregate is still in an uncommitted state, because then we'll lose the original version number and won't be able to do optimistic concurrency control. Consider the following scenario:

  1. Aggregate is rehydrated (version = 5)
  2. Event is applied (version = 5, # uncommitted events = 1)
  3. Another event is applied (version = 5, # uncommitted events = 2)
  4. Aggregate is saved in repository (expected version = 5, new version = (5 + 2 =) 7, we can do optimistic concurrency control here. If the expected version differs from the version currently in the repository, throw a ConcurrencyException)
  5. MarkChangesAsCommitted is called on aggregate (version = 7, # uncommitted events = 0)
  6. Rinse & repeat...

@Narvalex
Copy link

We do not lose the original version number at all.

  1. Aggregate is rehydrated (version = 5)
  2. Event is applied (version = 6, #uncommittedEvents = 1)
  3. Another event is applied (version = 7, #uncommittedEvents = 2)
  4. Aggregate is saved in repository (expectedVersion = 5, newVersion = 7. Concurrency control is simple: expectedVersion (5) sould be equal to newVersion - #uncomittedEvents `(7 - 2) = 5

@amolenk
Copy link

amolenk commented Dec 13, 2015

True! That's a nice way to do the check.
I think I still prefer the Version to reflect the last 'committed' version instead of the 'new/dirty' version which may or may not become the next committed version, but you're right that it doesn't matter for concurrency checks.

@Narvalex
Copy link

Indeed. There are a lot of ways to do it right. For instance, in my own implementation of event store I do the concurrency check in another way

@darbio
Copy link

darbio commented Aug 30, 2019

@Narvalex your link is broken. Can you direct us to your implementation?

@Narvalex
Copy link

@darbio : Nowadays Im using EventStore, but back in the day I was inspired by this implementation of a pesimistic concurrency check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants