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

Transaction with two aggregates #149

Open
MatyMatousek opened this issue Nov 20, 2019 · 1 comment
Open

Transaction with two aggregates #149

MatyMatousek opened this issue Nov 20, 2019 · 1 comment

Comments

@MatyMatousek
Copy link

Hello,
I'm trying to figure out how to make a transaction on two aggregates. I have the first aggregate "sequencer" for numbers and the aggregate "ticket". It should work like this: I get a number from a sequencer, which I assign to the ticket and I create it. If the ticket creation return an error, I need to undo the assigned number and discard getNumber command.
Is there a solution for my use case? E.g. do a lock on both aggregates at the same time and after updating them make commit both aggregates.
I looked at your library for SAGA, but it is only for generating commands based on events but does not allow invalidating previous commands.

@nanov
Copy link
Contributor

nanov commented Nov 20, 2019

Hi!

Well you have a few options here, the one i would choose is not to implement the sequencer as an aggregate. There is one question that needs to be asked here:

  • Do you really need to 'undo' the number generation? Maybe having just ascending numbers ( who maybe not be always +1 ) works for you?

If so there are many ways to achieve this fairly cleanly, one idea that pops into mind is to use the aggregateId generation functionality ( async ) and then generate ids out of somewhere ( a mongo / redis collection and using the $inc operator will do for example ).

If having a following sequence number is a hard requirement and you, you could design a service with locks to generate those ids for you, or if you would like to do it with aggregates, i would implement something as following:

Two aggregates -> sequencer and ticket - as you have done.

For creating a ticket ( ie assigning a number ) you should do something as following :

command to sequencer -> CreateTicket -> increment seq ( event ) -> businessRule -> fire somehow a create command on the ticket aggregate with the sequence inside and wait for the result ( ie successful or not / created event whatever ) -> if the result is successful than the business rule is fine, otherwise reject the command.

Some things to have in mind:

  • Ticket aggregate can be created only from the sequencer one.
  • The sequence aggregate will be locked until the ticket is created successfully.
  • This creates a bottleneck on the ticket creation part.

Bear in mind that event with auto-incremented field in sql you don't get grantees that numbers will be always following, if a transaction is rolled back some numbers may be skipped.

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

2 participants