5

Hallo ich folgendes senario haben, die ich nicht verstehe, wie mit eventuellen Konsistenz erhalten:Domain Veranstaltungen und Versionierung ohne CQRS

  1. Benutzer 1 verwendet Name Kundenaufgabe basierend ui zu ändern
  2. App Dienst fordert Betrieb das Aggregat
  3. Aggregate Brände Ereignis auf Kundenname geändert
  4. Bus sendet Nachricht nservicebus
  5. nServicebus-Dienst stirbt
  6. Benutzer 2 erhält Aggregat und Anrufe Adresse ändern
  7. Aggregate Betrieb genannt
  8. Domain-Ereignis ausgelöst
  9. Nachricht auf dem Bus setzen
  10. Bus startet
  11. Nachricht 2 erste
  12. Nachricht 2 verarbeitet und andere Bounded abgeholt Kontext aktualisiert mit neuer Adresse
  13. Nachricht 1 abgeholt jetzt die falsche Reihenfolge
  14. Was passiert jetzt

In 13 würde es einen optimistischen Gleichzeitigkeitsfehler geben, wenn wir die Version des Aggregats im Ereignis weitergeben?

Wenn dies der Fall ist, wird Nachricht 1 new im anderen Kontext auf Objekt angewendet. Wie erhalten wir Konsistenz?

Dieses Problem verhindert, dass ich Ereignisse in meiner Domäne anwende. Alle helfen willkommen.

Die wesentliche Idee ist, ein anderes Aggregat in einem anderen Kontext zu aktualisieren. Ich bin nur auf die Nebenläufigkeit dieser Technik fest.

Wir verwenden kein Event Sourcing oder CQRS im Sinne von Commandhandler und Befehle drücken auf den Bus. Es ist nur die Ereignisverarbeitung, die wir asynchron durchführen möchten, da wir ein bestehendes Design haben, das wir nicht ändern wollen.

Blair

Antwort

3

Im Allgemeinen würden Sie die Nachrichten Warteschlangen werden. Wenn sie in eine Warteschlange gehen, erhalten Sie eine ordnungsgemäße Bestellung. Wenn Sie etwas verwenden möchten, das die Bestellung mit Ihrem Servicebus nicht unterstützt, fügen Sie Ihren Ereignissen eine Sequenznummer hinzu, damit die andere Seite sie richtig neu anordnen kann. TCP tut dies bereits seit 1981 http://www.ietf.org/rfc/rfc793.txt :)

+0

Ich bin mir nicht sicher, was du meinst. Ich schicke die Veranstaltung über Nservicebus, also gibt es keine Bestellung. Wenn ich eine Sequenznummer zu meinen Ereignissen hinzufüge, wie mache ich dann die Bestellung am anderen Ende? Was ich dort vermisse, muss etwas Offensichtliches sein, das ich nicht sehe. –

+0

Auch bei NService-Bus mit mehreren Threads gibt es keine Garantie, dass sie in der Reihenfolge verarbeitet werden. –

+0

Behalten Sie die Sequenznummer am anderen Ende im Auge. Verarbeiten Sie die Nachricht erst, wenn die Sequenznummer mit der zuletzt bearbeiteten Sequenznummer + 1 übereinstimmt. –

0

Oops: Ich habe gerade bemerkt, dass Sie tatsächlich verwendeten 2 verschiedene Aufgaben in Ihrem Beispiel (Name des Kunden und dann Kundenadresse). Natürlich wäre das kein Problem, da die Reihenfolge eigentlich keine Rolle spielt. Aber ich lasse meine Antwort für den Fall, dass Sie zwei gleiche Änderungen wünschen.

Wie immer ein paar Fragen/Probleme in den Sinn kommen:

Für eine Sache Ihr Beispiel seit 2 Benutzer die Adresse zur gleichen Zeit und die Reihenfolge der Verarbeitung aktualisieren konnte kein Endpunkt erfordern zum Scheitern verurteilt kann zufällig sein. Die Frage wird also, welche die richtige Adresse ist.So Auflösung , dass erfordert ein bisschen mehr Analyse. Zum einen können wir davon ausgehen, dass ein Kunde sich nicht so häufig bewegen wird, dass 2 Benutzer die Adresse zur gleichen Zeit aktualisieren (oder sogar in der Nähe) ---

Auch dann ist vielleicht die erste Adresse das Richtige.

Ich denke für ein solches Szenario möchten Sie feststellen, ob Nebenläufigkeit oder sogar eine andere Toleranz ein Problem ist. Vielleicht wird eine Adresse nur einmal am Tag geändert und jede andere Änderung erfordert eine andere Interaktion. Daher wäre eine Ausnahmebehandlung eine Option.

Sie sollten dies nicht auf ein technisches Niveau reduzieren, um es zu lösen, sondern vielmehr die Auswirkungen auf Prozesse und Geschäfte betrachten.

Für eine einfache Lösung würde ich mit passender Nachricht Sendedatum auf das letzte Betriebsdatum für einen bestimmten Typ gehen. Also für ChangeAddressCommand bei der Verarbeitung einer Nachricht können Sie mit dem aktuellen LastAddressChange vergleichen und wenn die Nachricht vor dem letzten Änderungsdatum gesendet wurde, dann lehnen Sie es ab.

0

Eine ähnliche Frage mit NServiceBus wird here diskutiert. Das OP schlägt die Verwendung von IBus.HandleCurrentMessageLater() vor, bis die andere Nachricht ankommt. Dies kann funktionieren, kann aber problematisch sein, da Sie nie wissen, wie lange Sie warten müssen.

Eine kompliziertere Option wäre die Verwendung einer saga, die warten würde, bis alle Nachrichten, die zu einer bestimmten Version führen, angekommen sind. In diesem Fall erfolgt die Sequenzierung basierend auf der Version und ist nur möglich, wenn alle Änderungen in der Gesamtversion auf dem anderen BC veröffentlicht werden. Angenommen, Nachricht 1 funktionierte in Version 2 des Aggregats. Dann inkrementiert es die Version des Aggregats und veröffentlicht ein Ereignis, das besagt, dass es mit Version 2 gearbeitet hat. Nachricht 2 operiert auf Version 3 des Aggregats und veröffentlicht ein Ereignis, das besagt, dass es Version 3 verwendet hat. Wenn der NServiceBus-Endpunkt in dem anderen BC empfängt Nachricht 2 vor Nachricht 1, sie weiß, dass die letzte empfangene Nachricht auf Version 1 des Aggregats ausgeführt wurde, also benötigt sie eine, die auf Version 2 operiert hat. Sie startet eine Saga, die auf die nächste Nachricht wartet. Sobald die Nachricht Nachricht 1 empfängt, wendet die Saga Nachricht 1 und dann Nachricht 2 an und gibt den Saga-Status frei. Wenn die Verwendung der Version für die Sequenzierung nicht akzeptabel ist, kann eine andere Sequenzierungsstrategie verwendet werden.

0

Nach this sollten Sie sich fragen:

Was ist der geschäftlichen Auswirkungen eines Ausfalls zu haben?

In Ihrem aktuellen Fall haben Sie dieses Problem einmal durch eine Million Anfragen. Ich glaube nicht, dass es einen großen Einfluss auf das Geschäft hätte, wenn Sie beide Anfragen als gültig akzeptieren würden.