2015-09-28 5 views
5

Veuillez expliquer pourquoi la modification de plusieurs agrégats en même temps est une mauvaise idée lorsque vous effectuez des opérations CQRS, ES et DDD. Y a-t-il des situations où cela pourrait encore être acceptable?Pourquoi limiter les commandes et les événements à un agrégat? CQRS + ES + DDD

Prenez par exemple une commande telle que PurgeAllCompletedTodos. Je veux que cette commande mène à un événement qui met à jour l'état de chaque Todo-agrégat terminé en affectant à IsActive la valeur false.

Pourquoi est-ce que ce n'est pas bon?

Une raison pour laquelle je pouvais penser:

Lorsque la mise à jour de l'état de domaine, il est probablement bon de limiter la transaction à une partie bien définie de tout l'État de sorte que seule cette partie doivent être verrouillée en écriture lors de la mise à jour. Cela permettrait de nombreuses écritures sur des agrégats différents en parallèle, ce qui pourrait améliorer les performances dans certains scénarios extrêmement lourds.

+0

« Est-ce qu'un événement * pas * mettre à jour tout état de domaine du tout? » et "Pourquoi limiter les commandes et les événements à 1 agrégat?" semble être deux questions distinctes, sans rapport avec moi. – guillaume31

+0

Oui, vous avez raison. Je vais modifier la question. –

+0

J'ai déplacé l'autre partie de ma question ici: http://stackoverflow.com/questions/32823747/in-es-cqrs-ddd-can-a-event-not-update-any-real-domain-state- tout à fait –

Répondre

9

La réponse à la question réside dans la signification de "agrégat". Comme première chose, je dirais que vous ne modifiez pas 'n' agrégats, mais que vous modifiez 'n' entités.

Un agrégat contient plus-que-une entité et il est juste un concept transaction , l'agrégat (modèle) est utilisé lorsque vous devez modifier l'état de plus d'une entité dans votre application transactionnellement (tous sont modifiés ou aucun).

Maintenant, pourquoi modifier plus d'un agrégat avec une commande?

Si vous en ressentez le besoin, avant de faire quoi que ce soit d'autre, vérifiez vos limites globales pour voir si vous pouvez le modifier pour supprimer les besoins de 1 commande -> 'n' aggregate.

Un agrégat peut contenir un grand nombre d'entités du même type, donc pour votre commande PurgeAllCompletedTodos, vous pourriez aussi penser à étendre la limite de transaction à partir d'une seule Todo à un UserTodosAggregate global qui contient tous les todos utilisateur, et laissez-le gérer toutes les commandes pour les todos d'un seul utilisateur.
De cette façon, vous pouvez modifier tous les todos d'un utilisateur en une seule transaction. Si cela ne résout toujours pas votre problème car, disons que c'est nécessaire pour purger tous les todos terminés de chaque utilisateur dans l'application, vous devrez toujours envoyer une commande à 'n' agrégats, la limite globale ne pas d'aide, donc nous pouvons penser à avoir un AllApplicationTodosAggregate qui gère la commande.
Probablement ce n'est pas la meilleure solution, car comme vous l'avez dit, cette commande bloquerait TOUS les todos de l'application, mais, vérifiez toujours si cela peut être un bon compromis (cette partie du blocage est très bien expliqué dans Blue Book et Red Book of DDD).

Et si j'ai besoin de modifier certaines entités et que je ne peux pas les avoir dans un seul agrégat?

Avec la précédente, une commande qui modifie plus d'un agrégat est mauvaise en raison des transactions. Que faire si vous modifiez 3 agrégats, le premier est bon, puis le serveur est arrêté?

Dans ce cas, ce que vous faites est d'avoir beaucoup de modification unique qui doit être géré pour éviter toute incohérence du système. Cela peut être fait en utilisant un gestionnaire de processus, dont les responsabilités sont modifier tous les agrégats en leur envoyant la bonne commande et gérer les échecs si elles se produisent.

Un agrégat reçoit encore sa propre commande, mais le gestionnaire de processus est chargé de les envoyer d'une manière qu'il sait (un à la fois, tout en parallèle, 5 par unité de temps, ce que-do-you-want)
Vous pouvez donc avoir une stratégie pour gérer l'échec entre deux transactions, et prendre une décision comme: "si quelque chose échoue, annule toutes les modifications effectuées jusqu'à maintenant" (envoi d'une commande de restauration à chaque agrégat) ou "si une opération échoue 3 fois toutes les 30 minutes et si cela ne fonctionne pas, retournez "," si quelque chose échoue, créez une notification pour l'administrateur système ".

(désolé pour le long courrier, au moins elle pourra être utile)

+0

Grande explication. Très bien expliqué. Merci! – Chris