Using a domain event template

I am trying to implement this template in a new project as described by udi dahan.

I like the idea if, but I'm still not quite sure in what cases it should be applied (for new things ...).

For example, let's say I have an OnUserCreated event. I want one of the handlers to send a confirmation email to the user. But what if the event quits, an email is sent, and then a transaction-related error occurs and the data is never stored in the database. Is the template applicable in this situation? I read that people say no, but some of the projects that I switched on really do that. Or is it something I should use only to download and update other objects ... On the other hand, I read that someone said that the related objects needed for the operation should already be loaded, so I should not download them from the database to the event.

+6
source share
2 answers

Of course, it depends on how you decide to implement your system.

Here you can consider several options:

1. Two-phase acceptance When performing two-phase commit, basically each handler contains 3 methods: one for Preparing, one for committing and one for rolling back.

For all event handlers, Prepare is first created. If none of these reports is a problem, all Commit () methods of the handlers are called. If any of these reports causes a problem - despite the absence of messages caused by Prepare () calls, then for all handlers whose Commit () has already been executed, you call their rollback () methods.

2. Internal and external event handlers Another option is to separate event handlers. You can post an event, such as UserCreated, which is handled by event handlers that take part in the transaction in the first place. The event is stored in the database as part of the transaction. Then you can have external event handlers that respond only to events that are already stored in the database - for example, the sender of the email. They can only be called after the initial transaction has been completed.

I'm sure you can come up with more ways to handle your specific scenario.

+7
source

Using domain events allows you to move certain actions (sending emails) outside of a business transaction (creating a user). Event publishing is logged in the same transaction as transaction db, so if transaction db fails, events will not be published. Using a long-term message queuing system (msmq) ensures that if an event is posted, the handler will ultimately be executed.

Your stream should look something like this:

Begin Transaction Receive Command Call Aggregate Method Publish Events // will only be published if the transaction succedes Commit Transaction Begin Transaction Receive Event Send Email End Transaction 

As a side note, try to name your events without the "On" prefix, as it’s easier to use them in sentences.

+3
source

Source: https://habr.com/ru/post/886416/


All Articles