|
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