ProgrammationDéveloppeur Backend

Parlez-nous en détail de la spécificité du travail avec des transactions en SQL. Comment contrôler l'intégrité des données lors d'un accès simultané à une table depuis différentes sessions ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En SQL, les transactions permettent de regrouper plusieurs opérations (insert/update/delete) en une seule unité de travail atomique, qui peut être soit entièrement appliquée, soit annulée. Le cycle de vie d'une transaction est construit autour des commandes :

  • BEGIN ou START TRANSACTION — début de la transaction ;
  • COMMIT — validation des modifications ;
  • ROLLBACK — annulation de toutes les modifications au sein de la transaction.

SQL prend en charge les niveaux d'isolation des transactions (Read Uncommitted, Read Committed, Repeatable Read, Serializable), qui définissent la visibilité des données entre les transactions parallèles et protègent contre des problèmes tels que les "lectures sales" ou les "lignes fantômes".

Pour contrôler l'intégrité des données, il est nécessaire de choisir judicieusement :

  • Le niveau d'isolation (par exemple, pour les applications bancaires — probablement Serializable).
  • La gestion explicite des transactions, surtout là où une entité est modifiée simultanément (par exemple, SELECT ... FOR UPDATE).

Exemple sur PostgreSQL :

BEGIN; -- Obtenir et bloquer la ligne du produit SELECT * FROM inventory WHERE id = 1 FOR UPDATE; UPDATE inventory SET quantity = quantity - 1 WHERE id = 1; COMMIT;

Question piégée

Quel niveau d'isolation est défini par défaut dans les SGBD populaires (PostgreSQL, MySQL) et en quoi diffère-t-il de SERIALIZABLE ?

Réponse:
Dans PostgreSQL, le niveau par défaut est Read Committed — dans ce cas, la transaction ne voit que les données validées au moment de la requête, mais des "lectures non répétées" (non-repeatable reads) sont possibles.
Dans MySQL (InnoDB) — Repeatable Read. La différence avec Serializable est que seul ce dernier empêche complètement tout changement fantôme ou parallèle, mais fonctionne de manière perceptiblement plus lente en raison des blocages globaux.

Exemple :

-- En Repeatable Read, SELECT peut renvoyer les mêmes lignes, tandis qu'en Read Committed, de nouvelles lignes peuvent apparaître entre deux SELECT dans la transaction.

Histoire

Dans un grand système financier, lors de transferts massifs entre comptes avec un faible niveau d'isolation (Read Committed), des situations se produisaient où un même solde était utilisé simultanément par plusieurs transactions. Cela entraînait un double encaissement (condition de concurrence). Après être passé à Serializable et une gestion appropriée des verrouillages, le problème a disparu.


Histoire

Dans le commerce électronique, une transaction avec UPDATE product SET stock = stock - 1 sans être enveloppée dans une transaction entraînait la vente de plus de produits que disponibles en stock. Le problème n'a été identifié qu'avec un volume élevé de commandes concurrentes. La solution — utiliser des transactions et un verrouillage des lignes via SELECT ... FOR UPDATE.


Histoire

Dans un système logistique, dans l'une des tables lors de mises à jour fréquentes, on a oublié le commit explicite. En cas de panne, une partie des données était perdue à cause de l'autocommit ou d'un rollback incorrect. Le résultat — perte d'enregistrements et audit coûteux.