|
1 | 1 | .. index::
|
2 | 2 | single: Messenger; Record messages
|
3 | 3 |
|
4 |
| -Record Events Produced by a Handler |
5 |
| -=================================== |
| 4 | +Events Recorder: Handle Events After CommandHandler Is Done |
| 5 | +=========================================================== |
6 | 6 |
|
7 |
| -In an example application there is a command (a CQRS message) named ``CreateUser``. |
8 |
| -That command is handled by the ``CreateUserHandler`` which creates |
9 |
| -a ``User`` object, stores that object to a database and dispatches a ``UserCreatedEvent``. |
| 7 | +Let's take the example of an application that has a command (a CQRS message) named |
| 8 | +``CreateUser``. That command is handled by the ``CreateUserHandler`` which creates |
| 9 | +a ``User`` object, stores that object to a database and dispatches a ``UserCreated`` event. |
10 | 10 | That event is also a normal message but is handled by an *event* bus.
|
11 | 11 |
|
12 |
| -There are many subscribers to the ``UserCreatedEvent``, one subscriber may send |
13 |
| -a welcome email to the new user. Since we are using the ``DoctrineTransactionMiddleware`` |
14 |
| -we wrap all database queries in one database transaction and rollback that transaction |
15 |
| -if an exception is thrown. That means that if an exception is thrown when sending |
16 |
| -the welcome email, then the user will not be created. |
| 12 | +There are many subscribers to the ``UserCreated`` event, one subscriber may send |
| 13 | +a welcome email to the new user. We are using the ``DoctrineTransactionMiddleware`` |
| 14 | +to wrap all database queries in one database transaction. |
17 | 15 |
|
18 |
| -The solution to this issue is to not dispatch the ``UserCreatedEvent`` in the |
| 16 | +**Problem:** If an exception is thrown when sending the welcome email, then the user |
| 17 | +will not be created because the ``DoctrineTransactionMiddleware`` will rollback the |
| 18 | +Doctrine transaction, in which the user has been created. |
| 19 | + |
| 20 | +**Solution:** The solution is to not dispatch the ``UserCreated`` event in the |
19 | 21 | ``CreateUserHandler`` but to just "record" the events. The recorded events will
|
20 | 22 | be dispatched after ``DoctrineTransactionMiddleware`` has committed the transaction.
|
21 | 23 |
|
@@ -69,6 +71,7 @@ in the middleware chain.
|
69 | 71 | $user = new User($command->getUuid(), $command->getName(), $command->getEmail());
|
70 | 72 | $this->em->persist($user);
|
71 | 73 |
|
| 74 | + // "Record" this event to be processed later by "handles_recorded_messages". |
72 | 75 | $this->eventRecorder->record(new UserCreatedEvent($command->getUuid());
|
73 | 76 | }
|
74 | 77 | }
|
0 commit comments