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 :
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;
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é à
Serializableet une gestion appropriée des verrouillages, le problème a disparu.
Histoire
Dans le commerce électronique, une transaction avec
UPDATE product SET stock = stock - 1sans ê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 viaSELECT ... 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.