GH GambleHub

Modèle de saga et transactions distribuées

Modèle de saga et transactions distribuées

1) Pourquoi les sagas sont nécessaires

L' 2PC classique (verrouillage biphasé) est peu évolutif, complexe sous les pannes et bloque les ressources. La saga décompose le processus métier global en une séquence de transactions locales (étapes), chacune communiquant indépendamment. En cas d'échec, les étapes suivantes sont annulées et les étapes déjà exécutées sont compensées par des opérations inversées.
Résultat : une consistance eventual gérée sans blocage global, une haute résilience et un protocole de récupération clair.

2) Modèles de base

2. 1 Orchestration

Le coordinateur dédié de la saga gère les étapes : envoie les commandes, attend les réponses/événements, initie les compensations.
Avantages : contrôle centralisé, simple observation, debline explicite. Inconvénients : composant supplémentaire.

2. 2 Chorégraphie

Pas de coordonnateur ; les services réagissent les uns aux autres aux événements (« OrderPlaced » → « PaymentCaptured » → « InventoryReserved »...).
Avantages : faible connectivité. Inconvénients : plus difficile à tracer, le risque d'une « danse de la mort » sans règles claires.

2. 3 TCC (Try-Confirm/Cancel)

Option avec gel des ressources :

1. Try - préparation/réserve,

2. Confirm - fixation,

3. Cancel est un retour en arrière.

Les garanties sont plus élevées, mais les contrats et les délais des réserves sont plus difficiles.

3) Contrats d'étape et de compensation

Chaque étape = transaction locale + compensation (idempotent, permet la répétition).
L'indemnisation n'est pas obligée de « rendre la paix » - l'équivalence de domaine est suffisante (par exemple, « rembourser » au lieu de « supprimer le paiement »).
Identifiez les invariants : pour l'argent - le solde ne va pas dans le négatif ; pour les commandes - pas de statuts « dépendants ».
Entrez les réserves deadline/TTL et le « collecteur de garbage » pour les tentatives tardives.

4) Cohérence et sémantique de la livraison

Livraison des messages : at-least-once (défaut) → toutes les opérations doivent être idempotentes.
Ordre : important par la clé de corrélation (par exemple, 'order _ id', 'player _ id').
Exactly-once n'est pas le but de la saga ; Nous réalisons une efficacité exactement une seule fois à travers des clés idempotentes, outbox/inbox et une bonne communication.

5) L'état de la saga et son journal

Que stocker :
  • « saga _ id », « correlation _ id », état actuel (Running/Completed/Compensating/Compensated/Failed),
  • l'étape et ses variables (ID de paiement/réserves),
  • historique (journal) des événements/décisions, timestemps, deadlines, nombre de retraits.
Où stocker :
  • Une Saga Store distincte (table/document), accessible au coordinateur.
  • Pour la chorégraphie, les « agents » locaux de la saga publient les événements de statut dans le top général.

6) Modèles de publication fiable : outbox/inbox

Outbox : l'étape commit les modifications et écrit l'événement/commande dans la table outbox dans la même transaction ; worker publie dans le pneu.
Inbox : le consommateur tient à jour une table de traitement 'message _ id' → dedup + idempotence.
Après un effet secondaire réussi commitim offset/ACK (Kafka/RabbitMQ) - pas avant.

7) Concevoir les étapes de la saga

7. 1 Exemple (achat dans iGaming/e-commerce)

1. PlaceOrder → le statut 'PENDING'.
2. AuthorizePayment (Try) → `payment_hold_id`.
3. ReserveInventory → `reservation_id`.
4. CapturePayment (Confirm).
5. FinalizeOrder → `COMPLETED`.

Indemnisation :
  • si (3) l' → 'CancelPaymentHold'a échoué ;
  • si (4) a échoué après (3) le → « ReleaseInventory » ;
  • si (5) le → 'RefundPayment' et 'ReleaseInventory' échoue.

7. 2 Dédelines/Retraits

Maximum N rétroactifs avec retard exponentiel + jitter.
Une fois dépassé, passez à « Compensating ».
Gardez les next_attempt_at et les deadline_at pour chaque étape.

8) Orchestrateur vs plate-forme

Options :
  • Orchestrateur domestique léger (microservis + table Saga).
  • Plates-formes : Temporal/Cadence, Camunda, Netflix Conductor, Zeebe - donnent des minuteries, des retraits, des workflow de longue durée, de la visibilité et une console Web.
  • Pour la chorégraphie, utilisez le catalogue des événements et un accord strict sur les statuts/clés.

9) Protocoles d'intégration

9. 1 Asynchrone (Kafka/RabbitMQ)

Commandes : 'payments. authorize. v1`, `inventory. reserve. v1`.
Événements : 'payments. authorized. v1`, `inventory. reserved. v1`, `payments. captured. v1`, `payments. refunded. v1`.
Clé de lot = 'order _ id '/' player _ id' pour l'ordre.

9. 2 Synchrone (HTTP/gRPC) dans l'étape

Valide pour les étapes « courtes », mais toujours avec des délais/rétroactions/idempotence et fallback en compensation asynchrone.

10) Idempotence et clés

Dans les requêtes de commandes et de compensations, passez 'idempotency _ key'.
Les effets secondaires (enregistrement dans la base de données/radiation) sont conditionnels : « exécuter si vous n'avez pas encore vu 'idempotency _ key' ».
Les compensations sont également idempotentes : la répétition 'RefundPayment (id = X)' est sûre.

11) Traitement des erreurs

Classes :
  • Transient (réseaux/délais) → retrai/backoff.
  • Business (fonds insuffisants, limites) → compensation immédiate/voie alternative.
  • Irrecoverable (violation de l'invariant) → intervention manuelle, indemnisation « manuelle ».
  • Construisez une matrice de solutions : type d'erreur → action (retry/compensate/escalate).

12) Observabilité et SLO saga

SLI/SLO:
  • Fin de fin de la saga latitude (p50/p95/p99).
  • Taux de réussite (part des taux remplis sans compensation).
  • Mean time to compensate и compensation rate.
  • Orphaned sagas (suspendus) et le temps jusqu'à GC.
  • Trace : 'trace _ id '/' saga _ id' comme span link entre les étapes ; métriques burn-rate pour les budgets d'erreurs.

Logs : chaque changement d'état de la saga = enregistrement structuré avec raison.

13) Exemples (pseudo-code)

13. 1 Orchestrateur (idée)

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 (idée de table)


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 Chorégraphie (idées de thèmes)

`orders. placed '→ consommateurs : ' payments. authorize`, `inventory. reserve`

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

Tout refus → 'orders. compensate '→ est initié par' payments. cancel/refund`, `inventory. release`.

14) Comparaison avec les 2PC et ES

2PC : cohérence forte, mais blocages, goulots d'étranglement, « tuyaux de cuivre ».
Saga : consistance eventuelle, il faut une discipline de compensation et de télémétrie.
Event Sourcing : stocke les événements comme source de vérité ; les sagas y sont naturelles mais ajoutent de la complexité aux migrations/snapshots.

15) Sécurité et conformité

Security of Transport (TLS/mTLS), ACL per topic/queue.
Dans les événements - minimum PII, cryptage des champs sensibles, tokenization.
Vérification de l'accès aux sagas et aux registres de rémunération.
SLA avec des fournisseurs externes (paiements/livraison) = paramètres de déduplication et limites de rétractation.

16) Chèque de mise en œuvre (0-45 jours)

0-10 jours

Mettre en évidence les processus candidats (multiservices, avec compensation).
Sélectionnez le modèle (orchestration/chorégraphie/TSS) et la clé de corrélation.
Décrivez les étapes/compensations, les invariants et les dédouanements. Soulevez les tables 'saga', 'outbox', 'inbox'.

11-25 jours

Incluez outbox/inbox, idempotence et retraits avec backoff.
Déplucher les premières sagas ; ajoutez les dashboards SLI/SLO et la trace.
Écrivez un runbook de compensations (y compris manuelles) et d'escalade.

26-45 jours

Automatisez les sags « suspendus » GC, redémarrez/continuez périodiquement sur la deadline.
Passez la journée de jeu : échec de l'étape, dépassement de la date limite, indisponibilité du courtier.
Normalisez les contrats d'événements (versions, compatibilité), créez un « catalogue saga ».

17) Anti-modèles

« Compensation = delete de la base de données » au lieu d'une action inverse correcte du domaine.
Aucun outbox/inbox → perte d'événements/double effet.
Retraits sans jitter → DDoS de dépendance.
L'attente d'une forte cohérence en lecture sans « traitement en cours »....
Un orchestre géant pour tout → monolithe de contrôle.
Chorégraphie totale sans visibilité et SLA → danse incontrôlable.
Ignorer les deadlines → les réserves/holds éternels.

18) Métriques de maturité

≥ 90 % des processus critiques sont couverts de sagas/compensations et ont des invariants décrits.
Outbox/inbox est intégré pour tous les vendeurs/consumers de Tier-0/1.
SLO : p95 end-to-end de la saga est normal, taux de réussite stable, orphaned <cible.
Trace transparente et dashboards « par étapes », burn-rate alerte.
Jeu-jour trimestriel et vérification des runbook-compensations manuelles.

19) Conclusion

La saga est un contrat pratique de cohérence pour les systèmes distribués : étapes claires et actions rétroactives, discipline de publication (outbox/inbox), dédelines et retraits, observabilité et processus de compensation. Choisissez un modèle (orchestration/chorégraphie/TSS), fixez les invariants et les clés, rendez les gestionnaires idempotent - et vos processus d'affaires multiservices deviendront prévisibles et durables sans 2PC coûteux.

Contact

Prendre contact

Contactez-nous pour toute question ou demande d’assistance.Nous sommes toujours prêts à vous aider !

Commencer l’intégration

L’Email est obligatoire. Telegram ou WhatsApp — optionnels.

Votre nom optionnel
Email optionnel
Objet optionnel
Message optionnel
Telegram optionnel
@
Si vous indiquez Telegram — nous vous répondrons aussi là-bas.
WhatsApp optionnel
Format : +code pays et numéro (ex. +33XXXXXXXXX).

En cliquant sur ce bouton, vous acceptez le traitement de vos données.