GH GambleHub

Saga-Muster und verteilte Transaktionen

Saga-Muster und verteilte Transaktionen

1) Warum brauchen wir Sagas

Die klassische 2PC (Zwei-Phasen-Fixierung) ist schlecht skalierbar, kompliziert unter Ausfällen und blockiert Ressourcen. Die Saga unterteilt den gesamten Geschäftsprozess in eine Abfolge lokaler Transaktionen (Schritte), die jeweils unabhängig voneinander ausgeführt werden. Im Falle eines Fehlers werden die nachfolgenden Schritte abgebrochen und die bereits durchgeführten - werden durch umgekehrte Operationen kompensiert.
Das Ergebnis: eine überschaubare Ereigniskonsistenz ohne globalen Lockdown, eine hohe Überlebensfähigkeit und ein klares Wiederherstellungsprotokoll.

2) Basismodelle

2. 1 Orchestrierung

Ein dedizierter Saga-Koordinator verwaltet die Schritte: sendet Befehle, wartet auf Antworten/Ereignisse, initiiert Kompensationen.
Vorteile: zentrale Kontrolle, einfache Beobachtbarkeit, klare Fristen. Nachteile: zusätzliche Komponente.

2. 2 Choreographie

Kein Koordinator; Die Dienste reagieren auf die Ereignisse des anderen („OrderPlaced“ → „PaymentCaptured“ → „InventoryReserved“...).
Vorteile: schwache Konnektivität. Nachteile: schwieriger zu verfolgen, das Risiko eines „Todestanzes“ ohne klare Regeln.

2. 3 TCC (Try-Confirm/Cancel)

Option mit „Einfrieren“ von Ressourcen:

1. Try - Vorbereitung/Reserve,

2. Confirm - Fixierung,

3. Abbrechen - Rollback.

Die Garantien sind höher, aber die Verträge und Zeiträume der Reserven sind komplizierter.

3) Stufen- und Vergütungsverträge

Jeder Schritt = lokale Transaktion + Kompensation (idempotent, erlaubt Wiederholung).
Die Entschädigung ist nicht zur vollständigen „Rückgabe der Welt“ verpflichtet - eine Domänenäquivalenz reicht aus (z.B. „Rückzahlungszahlung“ statt „Zahlung löschen“).
Identifizieren Sie Invarianten: für Geld - das Gleichgewicht geht nicht ins Minus; für Bestellungen - keine „hängenden“ Status.
Geben Sie Deadlines/TTL-Reserven und einen „Garbage Collector“ für überfällige Versuche ein.

4) Konsistenz und Semantik der Lieferung

Zustellung von Nachrichten: at-least-once (Standard) → alle Transaktionen müssen idempotent sein.
Reihenfolge: Wichtig durch den Korrelationsschlüssel (z.B. 'order _ id', 'player _ id').
Exactly-once ist nicht das Ziel der Saga; Wir erreichen eine effektive Just-in-One-Genauigkeit durch idempotente Schlüssel, Outbox/Inbox und korrekte Commitation.

5) Der Zustand der Saga und ihr Log

Was zu lagern:
  • „saga _ id“, „correlation _ id“, aktueller Status (Running/Completed/Compensating/Compensated/Failed),
  • Schritt und seine Variablen (IDs der Zahlungen/Reserven),
  • Historie (Log) von Ereignissen/Entscheidungen, Zeitstempel, Deadlines, Anzahl der Retrays.
Wo zu speichern:
  • Ein separater Saga Store (Tabelle/Dokument), der dem Koordinator zur Verfügung steht.
  • Für die Choreografie sind es lokale „Agenten“ der Saga, die Statusereignisse in ein gemeinsames Topic veröffentlichen.

6) Zuverlässige Veröffentlichungsmuster: outbox/inbox

Outbox: Schritt, um Änderungen zu initiieren und das Ereignis/den Befehl in der Outbox-Tabelle in einer einzigen Transaktion zu schreiben; worker postet im Reifen.
Inbox: Der Verbraucher führt eine Tabelle der verarbeiteten 'message _ id' → dedup + idempotency.
Nach der erfolgreichen Nebenwirkung des commitime offset/ACK (Kafka/RabbitMQ) - nicht früher.

7) Entwerfen von Saga-Schritten

7. 1 Beispiel (Kauf bei iGaming/E-Commerce)

1. PlaceOrder → den Status „PENDING“.
2. AuthorizePayment (Try) → `payment_hold_id`.
3. ReserveInventory → `reservation_id`.
4. CapturePayment (Confirm).
5. FinalizeOrder → `COMPLETED`.

Entschädigung:
  • wenn (3) die → "CancelPaymentHold' fehlgeschlagen ist;
  • wenn (4) nach (3) → 'ReleaseInventory' fehlgeschlagen ist;
  • wenn (5) die → 'RefundPayment' und 'ReleaseInventory' fehlgeschlagen ist.

7. 2 Deadlines/Retrays

Maximal N Retrays mit exponentieller Verzögerung + Jitter.
Nach Überschreitung - Übergang zu „Compensating“.
Bewahren Sie next_attempt_at und deadline_at für jeden Schritt auf.

8) Orchestrator vs Plattform

Die Optionen sind:
  • Easy Home Orchestrator (Microservice + Saga Tabelle).
  • Plattformen: Temporal/Cadence, Camunda, Netflix Conductor, Zeebe - geben Timer, Retrays, langlebige Workflows, Sichtbarkeit und eine Web-Konsole.
  • Verwenden Sie für die Choreographie einen Veranstaltungskatalog und eine strenge Status-/Schlüsselvereinbarung.

9) Integrationsprotokolle

9. 1 Asynchron (Kafka/RabbitMQ)

Befehle: 'Zahlungen. authorize. v1`, `inventory. reserve. v1`.
Ereignisse: 'Zahlungen. authorized. v1`, `inventory. reserved. v1`, `payments. captured. v1`, `payments. refunded. v1`.
Partienschlüssel = 'order _ id '/' player _ id' für die Reihenfolge.

9. 2 Synchron (HTTP/gRPC) innerhalb eines Schritts

Zulässig für „kurze“ Schritte, aber immer mit Timeouts/Retrays/Idempotenz und Fallback in asynchroner Kompensation.

10) Idempotenz und Schlüssel

Bei Befehls- und Ausgleichsanfragen 'idempotency _ key' übergeben.
Nebenwirkungen (DB-Eintrag/Abschreibung) werden bedingt durchgeführt: „ausführen, wenn noch nicht gesehen 'idempotency _ key'“.
Auch die Entschädigungen sind idempotent: Eine Wiederholung von 'RefundPayment (id = X)' ist sicher.

11) Fehlerbehandlung

Klassen:
  • Transient (Netzwerke/Timeouts) → Retrays/Backoff.
  • Geschäft (unzureichende Mittel, Grenzen) → sofortige Entschädigung/alternativer Weg.
  • Irrecoverable (Invarianzverletzung) → manueller Eingriff, „manuelle“ Kompensation.
  • Erstellen Sie eine Entscheidungsmatrix: Fehlerart → Aktion (retry/compensate/escalate).

12) Beobachtbarkeit und SLO sagen

SLI/SLO:
  • Ende-zu-Ende-Latenz der Saga (p50/p95/p99).
  • Erfolgsrate (Anteil der abgeschlossenen ohne Entschädigung).
  • Mean time to compensate и compensation rate.
  • Orphaned sagas (hängend) und die Zeit bis GC.
  • Trace: 'trace _ id '/' saga _ id' als Span-Link zwischen den Schritten; Burn-Rate-Metriken für Fehlerbudgets.

Protokolle: jede Änderung des Saga-Status = strukturierter Eintrag mit Ursache.

13) Beispiele (Pseudocode)

13. 1 Orchestrator (Idee)

python def handle(OrderPlaced e):
saga = Saga. start(e. order_id)
saga. run(step=authorize_payment, compensate=cancel_payment)
saga. run(step=reserve_inventory, compensate=release_inventory)
saga. run(step=capture_payment, compensate=refund_payment)
saga. run(step=finalize_order, compensate=refund_and_release)
saga. complete()

def run(step, compensate):
try:
step () # local transaction + outbox except Transient:
schedule_retry()
except Business as err:
start_compensation(err)

13. 2 Outbox (Tischidee)


outbox(id PK, aggregate_id, event_type, payload, created_at, sent_at NULL)
inbox(message_id PK, processed_at, status)
saga(order_id PK, state, step, next_attempt_at, deadline_at, context JSONB)
saga_log(id PK, order_id, time, event, details)

13. 3 Choreographie (Ideen der Themen)

`orders. placed '→ Verbraucher: ' Zahlungen. authorize`, `inventory. reserve`

`payments. authorized` + `inventory. reserved` → `orders. try_finalize`

Jede Ablehnung → 'orders. compensate' → initiiert 'Zahlungen. cancel/refund`, `inventory. release`.

14) Vergleich mit 2PC und ES

2PC: starke Konsistenz, aber Blockaden, Engpässe, „Kupferrohre“.
Saga: eventual consistency, wir brauchen die Disziplin der Kompensation und Telemetrie.
Event Sourcing: speichert Ereignisse als Quelle der Wahrheit; Die Sagas darauf sind natürlich, fügen aber die Komplexität der Migrationen/Snap-Shots hinzu.

15) Sicherheit und Compliance

Transportsicherheit (TLS/mTLS), ACL per topic/queue.
In den Ereignissen - Minimum PII, Verschlüsselung empfindlicher Felder, Tokenisierung.
Prüfung des Zugangs zu Sagas und Vergütungsprotokollen.
SLA mit externen Anbietern (Zahlungen/Versand) = Parameter für Fristen und Retraylimits.

16) Implementierung Checkliste (0-45 Tage)

0-10 Tage

Hervorhebung der Kandidatenprozesse (Multiservice, mit Kompensation).
Wählen Sie das Modell (Orchestrierung/Choreographie/TCC) und den Korrelationsschlüssel.
Beschreiben Sie die Schritte/Kompensationen, Invarianten und Deadlines. Heben Sie die Tabellen 'saga', 'outbox', 'inbox' an.

11-25 Tage

Aktivieren Sie Outbox/Inbox, Idempotenz und Backoff-Retrays.
Deployte die ersten Saga; SLI/SLO Dashboards und Trace hinzufügen.
Schreiben Sie ein Runbook von Entschädigungen (einschließlich manueller) und Eskalationen.

26-45 Tage

Automatisieren Sie GCs von „hängenden“ Sagen, periodische Neustarts/Fristfortsetzungen.
Verbringen Sie einen Spieltag: Schrittversagen, Überschreitung der Frist, Nichtverfügbarkeit des Brokers.
Standardisieren Sie Veranstaltungsverträge (Versionen, Kompatibilität), erstellen Sie ein „Saga-Verzeichnis“.

17) Anti-Muster

„Compensation = delete from DB“ statt domänenrichtiger Rückwirkung.
Keine Outbox/Inbox → Ereignisverlust/Doppeleffekte.
Retrays ohne Jitter → Selbst-DDoS-Abhängigkeiten.
Erwartung einer starken Konsistenz beim Lesen ohne „Verarbeitung im Gange“....
Ein gigantischer Orchestrator für alle → Kontrollmonolithen.
Totale Choreographie ohne Sichtbarkeit und SLA → unkontrollierbarer Tanz.
Das Ignorieren von Terminen → ewige Reserven/Holds.

18) Reifegradkennzahlen

≥ 90% der kritischen Prozesse werden durch Sagas/Kompensationen abgedeckt und haben die beschriebenen Invarianten.
Outbox/inbox sind für alle Tier-0/1-Produzenten/-Konsumenten integriert.
SLO: p95 Ende-zu-Ende-Saga normal, Erfolgsrate stabil, orphaned <Ziel.
Transparentes Tracing und Dashboards „in Schritten“, Burn-Rate-Alerts.
Vierteljährlicher Spieltag und Überprüfung der manuellen Runbook-Entschädigung.

19) Schlussfolgerung

Die Saga ist ein praktischer Konsistenzvertrag für verteilte Systeme: klare Schritte und Rückschritte, Publishing-Disziplin (Outbox/Inbox), Deadlines und Retrays, Beobachtbarkeit und Kompensationsprozesse. Wählen Sie ein Modell (Orchestrierung/Choreografie/TCC), fixieren Sie Invarianten und Schlüssel, machen Sie Handler idempotent - und Ihre Multi-Service-Geschäftsprozesse werden ohne teure 2PC vorhersehbar und nachhaltig.

Contact

Kontakt aufnehmen

Kontaktieren Sie uns bei Fragen oder Support.Wir helfen Ihnen jederzeit gerne!

Integration starten

Email ist erforderlich. Telegram oder WhatsApp – optional.

Ihr Name optional
Email optional
Betreff optional
Nachricht optional
Telegram optional
@
Wenn Sie Telegram angeben – antworten wir zusätzlich dort.
WhatsApp optional
Format: +Ländercode und Nummer (z. B. +49XXXXXXXXX).

Mit dem Klicken des Buttons stimmen Sie der Datenverarbeitung zu.