9

Ich bin ein wenig verwirrt über den Fluss in einem System, das Domänenereignisse verwendet, um das Lesemodell zu erstellen. Insbesondere, wie gehen wir mit der Tatsache um, dass der Benutzer erwartet, dass sich Daten (und seine Ansicht) ändern, wenn sie einen Befehl ausführen, aber aufgrund unserer Systemarchitektur (nicht blockierende Aufrufe zum Veröffentlichen von Ereignissen) ändert sich die tatsächliche Datenbank möglicherweise nicht vor dem Seite wird neu geladen?Anzeigen von Änderungen in der Ansicht bei Verwendung von CQRS & DDD mit Domänenereignissen & ServiceBus

Ich hoffe, das Design eines unserer Systeme mehr inline mit CQRS über Ereignisse und einen Service-Bus zu bewegen.

Sagen wir, mein Flow als solche geht:

  1. Schaltfläche Benutzer in View klickt Aufgabe der Entfernung von Zahlungsmethode von ihrem Konto auszuführen.

  2. Controller ruft PaymentMethodRemovalService auf und übergibt es accountId & paymentMethodId.

  3. Controller verwendet AccountRepository Konto abrufen und ruft account.RemovePaymentMethod (id)

  4. Konto, dass der Betrieb Ereignis PaymentMethodRemovedMessage (accountId, paymentMethodId)

  5. Weil Event-Publishing ist asynchron erfolgen kann und veröffentlicht validiert, Wir müssen jetzt von der Service- und Rückkehransicht vom Controller zurückkehren - , aber unsere tatsächlichen Daten werden noch nicht aktualisiert!

  6. Ein Handler, iHandle < PaymentMethodRemovedMessage>, das Ereignis hört und entfernt die aktuelle Zeile aus der DB

Also, was ist ein Kerl zu tun?

Ich könnte einfach sagen, entfernen Sie das Div, das die Zahlungsmethode angezeigt wurde. Dies funktioniert möglicherweise in einem AJAX-Szenario, aber was ist, wenn ich Post-Redirect-Get zur Unterstützung von Nicht-JavaScript-Clients verwende? Dann feuere ich meine Get und lese die Daten von der Abfrageseite der Dinge, möglicherweise bevor sie aktualisiert wird.

Zeige ich einfach eine Benachrichtigung, dass ihre Anfrage zum Entfernen der Zahlungsmethode eingereicht wurde? (was nicht nett zu sein scheint, ist sinnvoll, um eine Bestellung zu übermitteln, aber nicht zum Beispiel um eine Adresse zu ändern).

Gibt es eine Möglichkeit, implementierende Änderungen als entkoppelte asynchrone Ereignisse abzustimmen und die Benutzerdaten anzuzeigen, die ihre aktuelle Änderung widerspiegeln?

EDIT: Meine Frage ist sehr ähnlich zu CQRS, DDD synching reporting database ich zu sagen habe, die Antwort gibt und auch hier gegeben erwähnt, hat ein bisschen von einem Geruch zu ihm - Gerangel der UI-Update zu zeigen, die mit aus Band die DB lesen, sozusagen. Ich hoffte auf etwas saubereres.

Antwort

8

Wenn Sie in das Anfrage-/Antwort-Modell eingeschlossen sind, können Sie ein Korreliertes Anfrage/Antwort-Muster übernehmen. Einzelheiten finden Sie im Beispiel für Async-Seiten im NSB-Download. Dies zeigt Request/Response in einer ASP.NET-Einstellung. Es gibt einige ASP.NET MVC Beispiele da draußen, wenn das mehr Ihre Sache ist.

Wenn Sie die asynchrone Verarbeitung einführen, akzeptieren Sie, dass die Daten veraltet sind.Man kann argumentieren, dass die Daten beim Abfragen der Datenbank bereits alt sind (Netzwerklatenz, Renderzeit usw.). Da die Daten bereits alt sind, müssen wir fragen, wie alt ist gut genug?

Noch eine Sache zu betrachten ist, dass Ihre Verarbeitung ein bisschen außer Betrieb ist. Schritt 3 sollte den Befehl validieren, bevor er an den Server gesendet wird und dann die Schritte 3, 4 nach 6 kommen. Die Datenbank sollte nur aktualisiert werden, wenn der Befehl gültig ist und das Ereignis nur veröffentlicht werden soll, wenn die Datenbank erfolgreich aktualisiert wird.

0

Dieses Problem wird als "Eventual Consistency" bezeichnet. Es gibt klare Wege, sich ihr zu nähern. Der erste Punkt ist, dass jedes System eine konsistente Konsistenz hat, egal ob sie asynchrone Ereignisse verwenden oder nicht. Sie haben sich lediglich dafür entschieden, dies explizit zu machen, während die meisten anderen Systeme den Benutzer warten lassen, bis das Update abgeschlossen ist. Beide Ansätze sind gültig, solange sie explizit gewählt werden.

Vor einiger Zeit habe ich einen Blogbeitrag zu diesem Thema geschrieben, den Sie vielleicht hilfreich finden. Sie können es hier finden: 4 Ways to Handle Eventual Consistency on the UI

Hier ist eine kurze Version:

Option 1 - Verwenden Sie ein Bestätigungsfenster. Wenn Sie eine Banking-App auf Ihrem Telefon verwenden, haben Sie dies wahrscheinlich in Aktion gesehen. Überweisen Sie etwas Geld und am Ende des Vorgangs werden Sie zu einem Bestätigungsbildschirm geführt, bevor Sie zu Ihren Konten zurückkehren. Dies gibt dem System Zeit, um auf den neuesten Stand zu kommen.

Option 2 - Fake it. Wenn die Operation, die der Benutzer versucht, höchstwahrscheinlich erfolgreich ist, dann kann das Fälschen eine legitime Vorgehensweise sein. Dies wird oft beim Kauf von Tickets verwendet, die sehr gefragt sind. Ihre Transaktion wird möglicherweise ausgeführt, aber später stellt das Unternehmen fest, dass Ihr Ticket bereits einige Millisekunden zuvor verkauft wurde. Der Vorteil für das Unternehmen besteht darin, dass sie den Verkauf tätigen und nicht riskieren, beide Kunden zu verlieren. Solange das System sorgfältig gebaut wird, sollte diese Situation selten auftreten und daher insgesamt kein Problem darstellen.

Sie können auch Korrelations-IDs verwenden, um den Erfolg oder das Fehlschlagen von Operationen zu abonnieren.

Wie auch immer, hoffe, dass das einige Denkanstöße liefert.

Verwandte Themen