Hallo Habr! Ich präsentiere Ihnen die Übersetzung des Artikels "Pattern: Saga" von Chris Richardson.
Die Situation
Es gibt eine Anwendung, auf die das Muster " Datenbank pro Dienst" angewendet wurde. Jetzt hat jeder Anwendungsdienst eine eigene Datenbank. Einige Geschäftstransaktionen decken mehrere Dienste gleichzeitig ab. Daher ist ein Mechanismus erforderlich, um die Datenkonsistenz zwischen diesen Diensten sicherzustellen.
Beispiel: Stellen wir uns vor, wir entwickeln einen Online-Shop, in dem ein Kunde ein Kreditlimit hat. Der Antrag muss sicherstellen, dass die neue Bestellung das Kreditlimit des Kunden nicht überschreitet. Da Bestellungen und Kunden unterschiedliche Datenbanken sind, kann die Anwendung keine lokalen ACID-Transaktionen verwenden.
Das Problem
Wie kann die Datenkonsistenz zwischen Diensten sichergestellt werden?
Lösung
Jede Geschäftstransaktion, die mehrere Services umfasst, muss als Saga implementiert werden.
Eine Saga ist eine Sammlung lokaler Transaktionen. Jede lokale Transaktion aktualisiert die Datenbank und veröffentlicht eine Nachricht oder ein Ereignis, wodurch die nächste lokale Transaktion in der Saga initiiert wird. Wenn die Transaktion beispielsweise aufgrund eines Verstoßes gegen Geschäftsregeln fehlgeschlagen ist, werden in der Saga Ausgleichstransaktionen gestartet, bei denen Änderungen zurückgenommen werden, die durch frühere lokale Transaktionen vorgenommen wurden.

Es gibt zwei Möglichkeiten, Sagen zu koordinieren:
- Choreografie - Jede Transaktion veröffentlicht Ereignisse, die Transaktionen in anderen Diensten auslösen.
- Orchestrierung - Ein Orchestrator teilt den Teilnehmern mit, welche Transaktionen gestartet werden sollen.
Beispiel: Choreografie-basierte Saga

In einem Online-Shop mit einer choreografiebasierten Saga umfasst das Erstellen einer Bestellung die folgenden Schritte:
Order Service ( )
OrderCreated ()
erstellt eine Order ()
im Status Ausstehend (Ausstehend) und veröffentlicht das OrderCreated ()
Ereignis OrderCreated ()
Customer Service ( )
erhält eine Veranstaltung und versucht, eine Gutschrift für die Bestellung zu reservieren. Anschließend wird eines von zwei Ereignissen veröffentlicht: CreditReserved ()
oder CreditReserved ()
CreditLimitExceeded ()
- Der Bestellservice empfängt eine Veranstaltung und ändert den Bestellstatus in genehmigt (bestätigt) oder storniert (storniert).
Beispiel: Orchestersaga

In einem Online-Shop, der eine orchestrierungsbasierte Saga verwendet, umfasst das Erstellen einer Bestellung die folgenden Schritte:
Order Service ( )
CreateOrderSaga ()
erstellt eine Order ()
im Status Ausstehend (Ausstehend) und erstellt eine CreateOrderSaga ()
CreateOrderSaga ()
sendet den Befehl CreateOrderSaga ()
an den Customer Service ( )
Customer Service ( )
versucht, ein Darlehen für eine Bestellung zu reservieren, und sendet eine Antwort zurückCreateOrderSaga ()
erhält eine Antwort und sendet einen Befehl ApproveOrder ()
oder RejectOrder ()
im Order Service ( )
- Der Bestellservice ändert den Status der Bestellung in genehmigt (bestätigt) oder storniert (storniert).
Saga hat folgende Vorteile
- Ermöglicht einer Anwendung, die Datenkonsistenz zwischen Diensten aufrechtzuerhalten, ohne verteilte Transaktionen zu verwenden.
Die Saga hat die folgenden Nachteile
- Das Programmiermodell wird immer komplexer. Beispielsweise müssen Entwickler kompensatorische Transaktionen entwerfen, die Änderungen rückgängig machen, die zuvor in der Saga vorgenommen wurden.