Ich habe kürzlich angefangen, mich mit CQRS / ES zu beschäftigen, weil ich es möglicherweise bei der Arbeit anwenden muss. Es scheint in unserem Fall sehr vielversprechend, da es viele Probleme lösen würde.
Ich skizzierte mein grobes Verständnis, wie eine ES / CQRS-App in einem vereinfachten Banking-Anwendungsfall (Geld abheben) kontextualisiert aussehen sollte.
Um es zusammenzufassen, wenn Person A etwas Geld abhebt:
- ein Befehl wird ausgegeben
- Befehl wird zur Validierung / Verifizierung übergeben
- Ein Ereignis wird in einen Ereignisspeicher verschoben, wenn die Überprüfung erfolgreich war
- Ein Aggregator nimmt das Ereignis aus der Warteschlange, um Änderungen auf das Aggregat anzuwenden
Nach meinem Verständnis ist das Ereignisprotokoll die Quelle der Wahrheit, da es das Protokoll von FACTS ist, aus dem wir dann jede Projektion ableiten können.
Was ich in diesem großen Schema der Dinge nicht verstehe, ist das, was in diesem Fall passiert:
- Regel: Ein Saldo kann nicht negativ sein
- Person A hat einen Kontostand von 100e
- Person A gibt einen WithdrawCommand von 100e aus
- Validierungsausweise und MoneyWithdrewEvent des Ereignisses 100e werden ausgegeben
- In der Zwischenzeit gibt Person A einen weiteren WithdrawCommand von 100e aus
- Das erste MoneyWithdrewEvent wurde noch nicht aggregiert, daher besteht die Validierung, da die Validierungsprüfung für das Aggregat (das noch nicht aktualisiert wurde) durchgeführt wurde.
- MoneyWithdrewEvent von 100e wird ein anderes Mal ausgegeben
==> Wir befinden uns in einem inkonsistenten Zustand mit einem Kontostand von -100e und das Protokoll enthält 2 MoneyWithdrewEvent
Soweit ich weiß, gibt es verschiedene Strategien, um mit diesem Problem umzugehen:
- a) Fügen Sie die aggregierte Versions-ID zusammen mit dem Ereignis in den Ereignisspeicher ein. Wenn also beim Ändern eine Versionsinkongruenz auftritt, geschieht nichts
- b) einige Sperrstrategien anwenden, was impliziert, dass die Verifizierungsschicht irgendwie eine erstellen muss
Fragen zu den Strategien:
- a) In diesem Fall ist das Ereignisprotokoll nicht mehr die Quelle der Wahrheit, wie soll damit umgegangen werden? Außerdem sind wir zum Kunden zurückgekehrt, obwohl es völlig falsch war, die Auszahlung zuzulassen. Ist es in diesem Fall besser, Sperren zu verwenden?
- b) Sperren == Deadlocks, haben Sie Einblicke in die Best Practices?
Ist mein Verständnis für den Umgang mit Parallelität insgesamt korrekt?
Hinweis: Ich verstehe, dass dieselbe Person in einem so kurzen Zeitfenster nicht zweimal Geld abheben kann, aber ich habe ein einfaches Beispiel angeführt, um mich nicht in Details zu verlieren