Retour à l'accueil

Transactions multi-phases : implémentation d'opérations tolérantes aux pannes dans les DBMS

L'article explique l'implémentation des transactions multi-phases à l'aide d'opérations idempotentes pour assurer la tolérance aux pannes dans les DBMS. Les étapes de verrouillage, d'exécution et de déverrouillage sont considérées avec des exemples de code pour MongoDB.

Comment implémenter des transactions tolérantes aux pannes : décomposition étape par étape
Advertisement 728x90

Transactions résilientes : Opérations idempotentes en pratique

Les transactions multiphases garantissent l'intégrité des données en cas de panne grâce à des opérations idempotentes et un journal d'états. Cette approche fonctionne avec n'importe quelle base de données, y compris MongoDB, et évite les pertes de données dues à des coupures de courant ou des plantages système.

Fonctionnement des transactions multiphases

Les transactions se décomposent en étapes séquentielles, chacune enregistrée dans une table TRANSACTIONS dédiée. États clés :

  • blocking — verrouillage des comptes pour éviter les opérations concurrentes.
  • save_balance — capture des soldes initiaux dans le journal.
  • main — exécution du transfert principal de fonds.
  • unlock — libération des verrous après achèvement.
  • finished — état final pour les transactions réussies.

L'idempotence assure qu'une répétition d'étape après une panne ne corrompt pas les données. Par exemple, A := B + 1 est idempotent, contrairement à A := A + 1 — mais celle-ci peut se décomposer en deux étapes idempotentes.

Google AdInline article slot

Étapes d'implémentation avec exemples de code

Transférons 250 € du compte d'Assange à celui de l'Agent Y. Données initiales dans la table ACCOUNTS :

| ID | NAME | BALANCE | TR_ID |

|----|----------|---------|-------|

Google AdInline article slot

| 34 | Assange | 300 | null |

| 78 | Agent Y | 7 | null |

1. Verrouiller les comptes (STATUS='blocking')

D'abord, créer un enregistrement TRANSACTIONS :

Google AdInline article slot

| ID | FROM_ID | TO_ID | AMOUNT | FROM_BALANCE | TO_BALANCE | STATUS |

|----|---------|-------|--------|--------------|------------|----------|

| 172| 34 | 78 | 250 | null | null | blocking |

Le verrouillage utilise des commandes atomiques, par exemple en MongoDB :

db.accounts.updateOne(
  { ID: 34, TR_ID: null },
  { $set: { TR_ID: 172 } }
);

Si aucun document n'est mis à jour, le verrou a échoué — réessayer ou annuler. Trier les ID au préalable pour éviter les interblocages.

2. Capturer les soldes (STATUS='save_balance')

Après verrouillage, copier les soldes initiaux dans TRANSACTIONS — idempotent par conception :

db.transactions.updateOne(
  { ID: 172 },
  { $set: { FROM_BALANCE: 300, TO_BALANCE: 7, STATUS: 'save_balance' } }
);

3. Exécuter le transfert (STATUS='main')

Opération principale utilisant les soldes sauvegardés pour l'idempotence :

db.accounts.updateOne(
  { ID: 34, TR_ID: 172 },
  { $set: { BALANCE: 50 } } // 300 - 250
);

db.accounts.updateOne(
  { ID: 78, TR_ID: 172 },
  { $set: { BALANCE: 257 } } // 7 + 250
);

Mettre à jour le statut en 'unlock' seulement après application des changements.

4. Déverrouiller et finaliser (STATUS='unlock')

Libérer les verrous avec vérification TR_ID :

db.accounts.updateOne(
  { ID: 34, TR_ID: 172 },
  { $set: { TR_ID: null } }
);

Après déverrouillage des deux, passer le statut à 'finished'.

Avantages et limites

Avantages clés :

  • Tolérance aux pannes : Récupération de toute défaillance sans perte de données.
  • Idempotence : Réessais sécurisés, essentiels en systèmes distribués.
  • Polyvalence : Compatible avec toutes les bases, pas seulement MongoDB.
  • Cohérence : Intégrité des données à chaque étape.
  • Performance : Journalisation supplémentaire peut ralentir.

Inconvénients : complexité accrue et surcharge du journal. Pour les apps financières ou systèmes critiques, cela en vaut la peine.

Conseils pour développeurs

  • Exploiter les opérations atomiques de votre SGBD pour verrous et mises à jour.
  • Implémenter une logique de réessai pour les verrous échoués.
  • Tester les scénarios de crash, comme des arrêts brutaux de processus.
  • Trier les ID pour minimiser les risques d'interblocage.

Cela offre une fiabilité au niveau 2PC avec la flexibilité NoSQL.

— Editorial Team

Advertisement 728x90

Lire ensuite