How to handle a transaction in an event-driven architecture?

I am currently playing with DDD and CQRS, and I switched to an outdated application.

Let's say I have an Article object that I can vote on.

When voting is submitted for an article, I want to increase or decrease the counter corresponding to the value of the vote.

This counter is part of my query model, and therefore I donโ€™t think it is suitable for the domain model. For these reasons, I decided to write a CastArticleVoteService in which I put the business logic about the vote, and I send the event for processing by a special event handler, which in turn updates the counter in the database.

First of all, I was skeptical because I told myself: "Hey, the counter update process must be in the same transaction as the one that stores the data." But this is clearly not true if I have a polyglot persistence (i.e.: MySQL / Redis).

However, transactions are applied, how can I be sure that all event handlers are processed properly and my data is consistent? (here is my counter). (what about an asynchronous event handler?)

Any tips?

+1
php event-driven domain-driven-design cqrs
source share
2 answers

Ok, here is my question for your question:

event driven and CRQS also commonly use event sourcing as a template.

This means that your votes will not be stored as a counter ( state ), but rather as a vote up / down ( fact ).

In your scenario, to request how many votes an article has accumulated, you can read all the events associated with the aggregate and apply them one at a time (in memory) in the order in which they occurred and get the final state of this aggregate instance ( article ) .

Sometimes, when the volume of events is large, a snapshot is stored in the most recent facts that arise as a result of applying these events to the unit.

It is worth noting : be careful with side effects when applying events to get the condition. Because, if the event related to the vote led to the article closing, for example, and sending an email to the author, then you do not want this email to be sent again when these events are played.

Think of it as the financial equivalent of a debit / credit event at a bank. Banks do not just keep your balance. They actually store all your transactions, and then reconcile and update the balance.

Some transactions occur immediately if the debtor / creditor accounts are in the same bank.

What does this give you out of the box?

  • Scalability It is a write-optimized architecture that can handle larger requests to change the state of an application more quickly without transaction and blocking.
  • traceability when checking your system, you will not only find out where you are (current state), but also how / why you are there (events)

In addition, since you have a data stream in all user interactions with the system, you can subsequently use this data in different ways for new functions that you could not think about from the very beginning of system design (for example, Google Analytics?)

Further reading:

+3
source share

Aggregates define transaction boundaries. When you decide, for an event-driven architecture, you decide on possible consistency. Therefore, you just need to choose: transaction OR event.

Please note that in most cases the final consistency is completely suitable for the business. These are only developers who have a transactional fetish implanted in lectures RDBMS / brainwashing at the university;)

+2
source share

All Articles