ADR-0005: Saga mit Kompensation für Überweisungen

Status

Akzeptiert, 2026-08-08

Kontext

Eine Überweisung verändert den Saldo von zwei Konten, die in accounts-service leben (siehe ADR-0003, Datenbank pro Service) - payments-service selbst besitzt keinen eigenen Zugriff auf Kontostände. Eine verteilte ACID-Transaktion über zwei Services hinweg (Two-Phase-Commit) würde eine enge technische Kopplung beider Services erzwingen (gemeinsamer Transaktionskoordinator, Sperren über Servicegrenzen hinweg) - genau das, was Microservice-Grenzen eigentlich vermeiden sollen (siehe ADR-0001 dieses Repos, allgemeiner: [microservices.io/patterns/data/saga.html]).

Entscheidung

payments-service orchestriert eine Saga mit explizitem Kompensationsschritt (InitiateTransferUseCase):

  1. Transfer wird als INITIATED persistiert, bevor irgendein Konto berührt wird.
  2. Abbuchung beim Quellkonto (POST /accounts/{iban}/withdrawals in accounts-service). Schlägt das fehl (z. B. keine Deckung, Konto nicht aktiv): TransferFAILED, Ende - es gibt nichts zu kompensieren, da noch keine Kontobewegung stattfand.
  3. Gutschrift beim Zielkonto (POST /accounts/{iban}/deposits). Schlägt das fehl (z. B. Zielkonto inzwischen geschlossen/eingefroren): die bereits erfolgte Abbuchung wird durch eine Gegenbuchung auf das Quellkonto rückgängig gemacht, TransferCOMPENSATED.
  4. Beide Schritte erfolgreich: doppelte Buchführung wird gebucht (LedgerBooking), TransferCOMPLETED.

Die Buchführung selbst (Debit-/Credit-Eintrag) erfolgt nach beiden erfolgreichen Kontobewegungen, nicht parallel dazu - das Ledger dokumentiert nur tatsächlich abgeschlossene Überweisungen.

Konsequenzen

Positiv

Negativ / Trade-offs

Alternativen erwogen

⌂ Cockpit