In some parts of the code, like this one :
ddd-forum/src/modules/users/useCases/createUser/CreateUserUseCase.ts :
const userOrError: Result<User> = User.create({
email, password, username,
});
if (userOrError.isFailure) {
return left(
Result.fail<User>(userOrError.getErrorValue().toString())
) as Response;
}
const user: User = userOrError.getValue();
await this.userRepo.save(user);
return right(Result.ok<void>())
} catch (err) {
return left(new AppError.UnexpectedError(err)) as Response;
}
we both need to send a domain event (here User.create will dispatch a UserCreated event) and update the database (here, await this.userRepo.save(user);).
But these operations need to be atomic to avoid inconsistencies.
In this example, once UserCreated is dispatched, it is then listened by the forum module which will create a new member based on this event.
This means that if this database persist operation fails :
await this.userRepo.save(user);
we will have a member created without its associated user.
In some parts of the code, like this one :
ddd-forum/src/modules/users/useCases/createUser/CreateUserUseCase.ts
:we both need to send a domain event (here
User.create
will dispatch aUserCreated
event) and update the database (here,await this.userRepo.save(user);
). But these operations need to be atomic to avoid inconsistencies. In this example, onceUserCreated
is dispatched, it is then listened by the forum module which will create a newmember
based on this event. This means that if this database persist operation fails :we will have a
member
created without its associateduser
.To avoid that, the outbox pattern must be implemented. Here is a reference explaining the problem and the solution : https://microservices.io/patterns/data/transactional-outbox.html .
What do you think ?