2015-09-28 1 views
5

Bitte erläutern Sie, warum das Ändern vieler Aggregate zur gleichen Zeit eine schlechte Idee ist, wenn Sie CQRS, ES und DDD ausführen. Gibt es Situationen, in denen es noch in Ordnung sein könnte?Warum Befehle und Ereignisse auf ein Aggregat beschränken? CQRS + ES + DDD

Nehmen Sie zum Beispiel einen Befehl wie PurgeAllCompletedTodos. Ich möchte, dass dieser Befehl zu einem Ereignis führt, das den Status jedes abgeschlossenen Todo-Aggregats aktualisiert, indem er IsActive auf false setzt.

Warum ist das nicht gut?

Ein Grund, warum ich denken konnte:

Wenn der Domänenzustand zu aktualisieren ist es wahrscheinlich gut, um die Transaktion zu einem gut definierten Teil des gesamten Staates zu begrenzen, so dass nur dieser Teil während der Aktualisierung gesperrt Schreib werden muß. Dies würde parallel viele Schreibvorgänge auf verschiedenen Aggregaten ermöglichen, was die Leistung in einigen extrem schweren Szenarien verbessern könnte.

+0

„Kann ein Ereignis * nicht * alle Domänenzustand überhaupt aktualisieren?“ und "Warum beschränken Sie Befehle und Ereignisse auf 1 Aggregat?" scheinen mir zwei getrennte, nicht verwandte Fragen zu sein. – guillaume31

+0

Ja, Sie haben Recht. Ich werde die Frage ändern. –

+0

Ich habe den anderen Teil meiner Frage hier verschoben: http://stackoverflow.com/questions/32823747/in-es-cqrs-ddd-can-a-event-not-update-any-real-domain-statate- bei allen –

Antwort

9

Die Antwort der Frage liegt in der Bedeutung von "Aggregat".

Als erstes würde ich sagen, dass Sie nicht 'n' Aggregate modifizieren, aber Sie modifizieren 'n' Entitäten.

Ein Aggregat enthält mehr-als-eine Einheit, und es ist nur ein Transaktion Konzept, das Aggregat (Muster) wird verwendet, wenn Sie den Zustand von mehr als einer Einheit in Ihrer Anwendung transaktions ändern müssen (alle sind modifiziert oder keine).

Nun, warum würden Sie mehr als ein Aggregat mit einem Befehl ändern?

Wenn Sie dies benötigen, bevor Sie etwas anderes tun, überprüfen Sie Ihre Aggregatgrenzen, um zu sehen, ob Sie sie ändern können, um die Anforderungen an 1 Befehl zu entfernen -> 'n' Aggregat.

Ein Aggregat kann eine Menge von Entitäten des gleichen Typs enthält, so für Ihren Befehl PurgeAllCompletedTodos, könnte man auch denken erweitert über die Transaktionsgrenze von einer einzelnen Todo zu einem Aggregate UserTodosAggregate das enthält alle user todos, und lassen Sie es alle Befehle für die Todos eines einzelnen Benutzers verwalten.
Auf diese Weise können Sie alle Todos eines Benutzers in einer einzigen Transaktion ändern.

Wenn dies Ihr Problem immer noch nicht löst, weil, sagen wir, dass alle abgeschlossenen Todos jedes Benutzers in der Anwendung gelöscht werden müssen, müssen Sie noch einen Befehl an 'n' Aggregate senden, die Aggregatgrenze doesn 't help, also können wir uns einen AllApplicationTodosAggregate vorstellen, der den Befehl verwaltet.
Wahrscheinlich ist dies nicht die beste Lösung, denn wie Sie es sagten, würde dieser Befehl ALLE Todos der Anwendung blockieren, aber, immer prüfen, ob es ein guter Kompromiss sein kann (dieser Teil der Blockierung wird in sehr gut erklärt beide Blue Book und Red Book von DDD).

Was passiert, wenn ich einige Entitäten ändern muss und sie nicht in einem einzigen Aggregat haben kann?

Mit dem vorherigen gesagt, ein Befehl, der mehr als ein Aggregat ändern, ist wegen der Transaktionen schlecht. Was ist, wenn Sie 3 Aggregate ändern, die erste ist gut, und dann wird der Server heruntergefahren?

In diesem Fall haben Sie eine Menge einzelner Änderungen, die verwaltet werden müssen, um Inkonsistenzen des Systems zu vermeiden. Es kann mit einem Prozess-Manager getan werden, der alle Aggregate ändern muss, die ihnen den richtigen Befehl senden, und Fehler verwalten, wenn sie auftreten.

Ein Aggregat erhalten noch eigene Befehl es ist, aber der Prozess-Manager ist verantwortlich für sie in einer Weise zu senden (eine zur Zeit, alle parallel, 5 pro Zeit, what-do-you-want) kennt
Sie können also eine Strategie zum Verwalten des Fehlers zwischen zwei Transaktionen haben und eine Entscheidung treffen wie: "Wenn etwas fehlschlägt, führen Sie alle bis jetzt vorgenommenen Änderungen zurück" (Senden eines Rollback-Befehls an jedes Aggregat) oder "wenn ein Vorgang fehlschlägt, wiederholen es 3 mal alle 30 Minuten und wenn nicht funktioniert, dann Rollback "," wenn etwas nicht funktioniert, erstellen Sie eine Benachrichtigung für den Systemadministrator ".

(sorry für den langen Pfosten, zumindest hoffe, es hilft)

+0

Große Erklärung. Sehr gut erklärt. Vielen Dank! – Chris

Verwandte Themen