How to handle transaction in event driven architecture?

*爱你&永不变心* 提交于 2020-01-14 05:21:12

问题


I'm currently playing with DDD & CQRS, and I moved forward a legacy application.

Let's say I have an Article entity, on which I can cast votes.

When a Vote is casted on an Article, I want to increment or decrement a counter accordingly to the value of the vote.

This counter is part of my Query model and thus I don't think it fits the Domain Model, for such reasons, I decided to write a CastArticleVoteService in which I put the business logic about a vote, and I dispatch an Event to be handle by a custom Event Handler which in turns update the counter in a database.

First of all, I was skeptical because I told myself "hey, the process of updating the counter should be in the same transaction as the one which persist the data". But that's obviously wrong if I have polyglot persistence (ie: MySQL / Redis).

However, the transaction stills apply, how could I be sure that the whole event handlers are processed properly and my data are consistent? (here my counter). (what about asynchronous events handler?)

Any tips?


回答1:


Alright, here is my take on your question:

In event driven & CRQS architecture, it is also common to use event sourcing as a pattern.

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

In your scenario, to query how many votes an article have accumulated, you can go read all the events related to an aggregate and apply them one by one (in memory) in the order they happened and get a final state of that aggregate instance (article).

Sometimes when the volume of events are big, a snapshot is kept on the most recent facts resulting from applying those events to an aggregate.

Worth noting: Be careful of side-effects when applying events to get state. Because if a vote up/down event caused an article to be closed for example and sent an email to the author, then you don't want that email to be sent again when replaying those events.

Think of this as the financial equivalent to debit/credit events in a bank. Banks don't just store your balance. They actually store all your transactions, and later do a reconciliation and update your balance.

Some transactions happen immediately if the debtor/creditor accounts are within the same bank

What that gives you out of the box?

  • Scalability; this is a write-optimised architecture that can handle larger requests to modify application state faster without transactions & locking
  • Traceability; when inspecting your system, not only you will find out where you're at (current state) but also you will know how/why you got there (events)

Also, since you have a data stream of all user interactions with the system, you can later use that data in different ways for new features that you would not have thought of from the beginning of designing the system (Analytics for example?)

Further reading:

  • Event Sourcing Pattern - Martin Fowler
  • Event Sourcing Basics - eventstore Db
  • Why Use Event Sourcing - Greg Young
  • MSDN: Event Sourcing Pattern
  • MSDN: Using Events in Highly Distributed Architectures



回答2:


Aggregates define transaction boundaries. When you decide for event-driven architecture then you decide for eventual consistency. So you just have to choose: transaction OR event.

Note that in most cases, eventual consistency is completely fine for the business. That's only devs who have a transactional fetish implanted by RDBMS lectures/brainwash on the university ;)



来源:https://stackoverflow.com/questions/22168363/how-to-handle-transaction-in-event-driven-architecture

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!