GH GambleHub

Sagas et transactions distribuées

La saga est une transaction commerciale à long terme divisée en une série d'étapes locales dans différents services/stockages. Chaque pas a une action de compensation qui fait reculer l'effet du pas en cas d'échec partiel. Contrairement aux 2PC/3PC, les sagas ne tiennent pas les verrous globaux et sont adaptées pour les microservices, les multi-régions et les charges élevées où la consistance eventuelle est autorisée.


1) Quand choisir des sagas (et quand - pas)

Convient :
  • Processus d'affaires longs/multiples (commande → paiement → réserve → livraison).
  • Différents domaines et entrepôts où il n'y a pas de transaction partagée.
  • Vous avez besoin d'une haute disponibilité et d'une mise à l'échelle horizontale.
Ne convient pas :
  • L'atomicité ACID solide est critique (par exemple, transférer de grandes sommes dans un seul registre).
  • Il n'y a pas de compensation claire (vous ne pouvez pas « réserver » ou annuler l'effet).
  • Les restrictions légales/réglementaires exigent un isolement strict et un invariant « instantané ».

2) Modèles de saga

1. Orchestration (Saga Orchestrator) : le coordinateur central gère les étapes et les rémunérations.

Avantages : flux explicite, contrôle des erreurs, télémétrie simplifiée.
Inconvénients : point de centralisation, risque d'un coordinateur « épais ».

2. Chorégraphie : Il n'y a pas de centre - les étapes sont initiées par des événements (« le service A a fait X → le service B réagit »).

Avantages : faible connectivité, mise à l'échelle simple.
Les moins : il est plus complexe traquer/debajit' le flux, le risque de "l'accroissement" des règles.

3. TCC (Try-Confirm/Cancel) : chaque étape est « redondance » (Try), puis confirmation (Confirm) ou annulation (Cancel).

Avantages : plus proche du protocole pseudo-biphasé, ressources gérables.
Inconvénients : plus coûteux dans la mise en œuvre des interfaces ; nécessite des timeouts des détenteurs de « Try ».


3) Conception de l'étape et de la compensation

Invariants : formulez clairement ce qui doit être vrai « avant/après » l'étape (par exemple « reste à ≥ 0 »).
Compensation ≠ transaction inverse : c'est une action logique qui annule l'effet métier (refund, release, restore).
Idempotence : l'étape et le compensateur doivent être répétés en toute sécurité (par "opération _ id').
Timeouts : chaque étape a deadline ; le retard déclenche l'indemnisation.
Effets non remboursables : enregistrez-les séparément (notifications, e-mail) et admettez « meilleur effet ».


4) Cohérence et ordre

Consistency eventual : les utilisateurs peuvent voir des écarts temporels ; UX - avec « attente « /spinners/statuts.
Ordre par clé : regroupez les étapes de commutation par clé d'entreprise (order_id) pour organiser les événements.
Déduplication : conservez le journal des traitements ('opération _ id' → status) avec la TTL.


5) Transport et fiabilité

Outbox pattern : écriture de l'événement dans la table locale « outbox » à l'intérieur de la même transaction, puis publication asynchrone dans le bus.
Inbox/Idempotency store : côté consommateur, le journal des messages déjà traités.
Exactly-once est efficace : « outbox + idempotent consumer » donne une pratique « exactement une fois ».
DLQ : pour les messages « toxiques » avec une riche méta-information et une redrave sûre.


6) Politiques d'erreur, retraits, backoff

Nous ne répétons que les étapes idempotentes ; les opérations d'écriture sont avec 'Idempotency-Key'.
Backoff + jitter exponentiel ; limitation des tentatives et de la date limite de la saga.
En cas de dégradation systémique - Circuit Breaker et graceful degradation (par exemple, annuler la partie mineure de la saga).
Conflits d'affaires ('409') - répétition après accord ou compensation et achèvement.


7) Orchestrateur : responsabilités et structure

Fonctions :
  • Suivi de l'état de la saga : 'PENDING → RUNNING → COMPENSATING → DONE/FAILED'.
  • Planifiez les étapes, les deadlines, les délais, les retraits.
  • Routage des événements et lancement des compensations.
  • Idempotence des opérations du coordinateur (journal des commandes).
  • Observabilité : corrélation 'saga _ id' dans les logs/tracés/métriques.
Stockage :
  • Tables 'saga', 'saga _ step', 'commands',' outbox '.
  • Index par 'saga _ id', 'business _ key', 'status', 'next _ run _ at'.

8) Chorégraphie : règles et protection contre le « coma des neiges »

Contrats d'événements : schémas et versioning (Avro/Proto/JSON Schema).
Sémantique claire : « événement de fait » vs « commande ».
L'arrêt de la chaîne : le service, après avoir détecté une incohérence, publie un événement 'Failed '/' Compensate'.
Alarme et alertes sur « boucles infinies ».


9) TCC : détails pratiques

Try : réserve de ressources avec TTL.
Confirmation : fixation, libération des blocages temporaires.
Cancel : réduction de la réserve (pas d'effets secondaires).
Collection Garbage : remplacement automatique Try après TTL (idempotent Cancel).
Idempotent Confirm/Cancel : la répétition est sûre.


10) Exemple (schéma verbal) - « Ordre avec paiement et livraison »

1. CreateOrder (localement) → outbox : 'OrderCreated'.
2. PaymentService : réserve « Try » (TCC) ; si le → 'PaymentReserved'réussit, si le → 'PaymentFailed' échoue.
3. InventoryService : réserve de marchandises ; avec l'inconvénient de → 'InventoryFailed'.
4. ShippingService : Création d'un slot de livraison (annulable).
5. Si n'importe quelle étape 'Failed' → l'orchestrateur déclenche la compensation dans l'ordre inverse : 'CancelShipping' → 'ReleaseInventory' → 'PaymentCancel'.
6. Si c'est OK → 'PaymentConfirm' →' OrderConfirmed '.


11) Pseudo-code de l'orchestre

pseudo startSaga(saga_id, order_id):
steps = [ReservePayment, ReserveInventory, BookShipment, ConfirmPayment]
for step in steps:
res = execWithRetry(step, order_id)
if!res.ok:
compensateInReverse(steps_done(order_id))
return FAIL return OK

execWithRetry(step, key):
for attempt in 1..MAX:
try:
return step.run(key)    # идемпотентно catch RetryableError:
sleep(backoff(attempt))
catch NonRetryableError:
return FAIL return FAIL

compensateInReverse(done_steps):
for step in reverse(done_steps):
step.compensate()       # идемпотентно

12) Observation et opérations SLO

Tracing : un seul 'saga _ id', les annotations 'step', 'attempt', 'decision' (run/compensate/skip).

Métriques :
  • Succès/erreur sag (%), durée moyenne, p95/p99.
  • La part des sagas indemnisés, les principales raisons des compensations.
  • Files d'attente/outbox laga, retraits par étapes.
  • Logis/audit : solutions orchestrales, identifiants de ressources, clés d'affaires.

13) Test et chaos

Injection d'erreurs à chaque étape : Timeouts, '5xx', conflits d'affaires.
Out-of-order événements, doublons, omissions (drop).
Les longues queues de latence → la vérification des dédelines et des compensations.
Les sagas de masse → la vérification WFQ/DRR et les caps dans les files d'attente, l'absence de « head-of-line blocking ».
Redrive de DLQ par étapes et par toute une saga.


14) Multi-ténacité, régions, conformité

Les balises 'tenant _ id/plan/region' dans les événements et les entrepôts sags.
Résidence : les données/événements ne quittent pas la région ; concevoir des sagas croisées régionales comme des fédérations de sagas locales + événements agrégateurs.
Priorité : les sagas VIP ont un poids de quota plus élevé ; isolation des workers per tenant.


15) Chèque-liste avant la vente

  • Chaque étape a un compensateur clair, les deux sont idempotentes.
  • Modèle choisi : orchestration/chorégraphie/TSS ; les limites de la responsabilité sont décrites.
  • Outbox/Inbox mis en œuvre, déduplication par 'opération _ id'.
  • Politiques rétrogrades : backoff avec jitter, limites de tentative et deadline générale de la saga.
  • Les contrats d'événements sont versionnés, il y a validation du schéma.
  • DLQ et redrive sécurisé sont personnalisés.
  • Télémétrie : métriques, tracing, corrélation "saga _ id'.
  • Playbooks opérationnels : cancel manuel/force-confirm, sabotage des sagas « accrochés ».
  • Les tests de chaos et de charge passent, SLO/budget des erreurs sont définis.

16) Erreurs typiques

Il n'y a pas de compensateur ou il est « impur » (a des effets secondaires).
Il n'y a pas d'idempotence/dedup - prises et balançoires d'états.
« Saga dans la saga » sans frontières explicites - cycles et blocages mutuels.
Pas de deadlines → des sagas « éternelles » et des fuites de ressources.
L'orchestre garde l'état « en mémoire » sans store stable.
Chorégraphie sans centre de télémétrie → défaillances « invisibles ».
UX opaque : les utilisateurs ne voient pas les statuts intermédiaires.


17) Recettes rapides

Classique SaaS : orchestration + outbox/inbox, backoff exponentiel, DLQ, statuts saga en UI.
Invariants forts sur la ressource : TCC avec TTL réserve et GC Cancel.
Volume/charge élevé : chorégraphie des événements + idempotence stricte et métriques par clé.
Multi-région : sagas locales + agrégats finaux ; éviter les blocages mondiaux.


Conclusion

Les sagas sont un moyen d'obtenir une cohérence prévisible dans les systèmes distribués sans blocage global. Les compensateurs clairs, l'idempotence, la livraison fiable (outbox/inbox), la discipline des timeouts et des retraits, ainsi que la télémétrie et les playbooks sont la clé pour que les processus commerciaux complexes restent durables et lisibles avec une augmentation de la charge de travail, du nombre de services et de la géographie.

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.