thenativeweb / node-eventstore

EventStore Implementation in node.js
http://eventstore.js.org/
MIT License
539 stars 116 forks source link

Duplicate revision id #72

Open mmmdreg opened 8 years ago

mmmdreg commented 8 years ago

I'm not sure if this is intentional feature or bug...

If I create two events for the same aggregateId at the same time using mongo store (haven't tried others), they are both commited successfully with the same revisionId. I would expect the store to throw for the second event so that it can retry (revalidate on the updated state and then commit if successful).

To illustrate this, given a bank account balance $5. If two commands come at the same time to withdraw $4 and withdraw $3, they will both validate against the perceived state ($5) and thus both will dispatch events, leading to the account being in negative balance.

Expected behavior would be for the first event to be commited to win, and the second to be forced to retry. In the above example, if the 4$ was withdrawn first, second command will be forced to retry against the new state ($1), not pass validation, and reject the command.

I imagine this could be worked around by using a synthetic eventId (e.g aggregateId-expectedRevisionId), but I would think the store should handle this behavior, allowing any arbitrary eventId (eg uuid).

Please correct me if my understanding is incorrect.

adrai commented 8 years ago

Are you using eventstore only or in combination with cqrs-domain?

adrai commented 8 years ago

This sort of features are handled by cqrs-domain.

mmmdreg commented 8 years ago

Interesting. Just using eventstore for now. So cqrs-domain is basically using another DB collection to keep track of locks on aggregates? What if the store just used a unique index on aggregateId/revisionId so it doesn't need a manual implementation in the command handler?

adrai commented 8 years ago

this is just a fallback... to really solve the problem in a distributed system you have to ensure all commands of the same aggregate instance will target the same worker process... so you have to solve it on a system level. i.e. with rabbitmq and consistent hash exchange

johanneslumpe commented 8 years ago

@adrai Don't want to hijack the topic but could you maybe explain consistent hash exchange a bit more? That seems quite relevant to issues I have been thinking about, i.e. two users issuing conflicting commands at ~ the same time to the same aggregate. If both get routed to the same worker then one of them will see an invalid state and can be rejected, effectively eliminating race conditions for a single aggregate in situations like this.

adrai commented 8 years ago

https://github.com/rabbitmq/rabbitmq-consistent-hash-exchange

Il giorno 11-set-2016, alle ore 23:47, Johannes Lumpe notifications@github.com<mailto:notifications@github.com> ha scritto:

@adraihttps://github.com/adrai Don't want to hijack the topic but could you maybe explain consistent hash exchange a bit more? That seems quite relevant to issues I have been thinking about, i.e. two users issuing conflicting commands at ~ the same time to the same aggregate. If both get routed to the same worker then one of them will see an invalid state and can be rejected, effectively eliminating race conditions for a single aggregate in situations like this.

You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/adrai/node-eventstore/issues/72#issuecomment-246207247, or mute the threadhttps://github.com/notifications/unsubscribe-auth/ABCS8jy13izxmn5LjWU34QWa9-VdrzI_ks5qpHiGgaJpZM4Iyl0s.