Transactions
Progression
#Transactions
ACID: Atomicité, Cohérence, Isolation, Durabilité. Les transactions encapsulent des modifications.
Objectifs d’apprentissage
- Expliquer ACID avec des exemples concrets (journal, fsync, MVCC/verrous).
- Choisir un niveau d’isolation en fonction des anomalies à éviter.
- Identifier lectures sales, non répétables, phantoms et write‑skew.
1begin;2insert into users values (3, 'Charlie');3rollback; -- annule la modification4 5begin;6insert into users values (3, 'Charlie');7commit; -- valide la modification
#Playground
#Animation: cycle de vie d’une transaction
#Niveaux d’isolation
- Read Uncommitted: peut voir des écritures non validées (rare, dangereux).
- Read Committed: pas de lectures sales; possibles lectures non répétables.
- Repeatable Read: empêche lectures non répétables; phantoms possibles (selon SGBD).
- Serializable: équivalent à un ordre sériel; le plus sûr, potentiellement le plus coûteux.
PostgreSQL/SQLite utilisent principalement MVCC (versions et snapshots) pour éviter les blocages de lecture. D’autres SGBD se basent plus sur des verrous de lignes/plages. Le comportement des anomalies varie.
#Anomalies courantes (exemples)
- Lectures sales: voir une écriture non validée (RU) → éviter en RC+.
- Lectures non répétables: relecture retourne une valeur différente (RC) → éviter en RR+.
- Phantoms: relecture d’un ensemble renvoie plus/moins de lignes (RR selon moteur) → éviter en Serializable.
- Write‑skew: deux transactions valident ensemble des mises à jour compatibles individuellement mais violant une contrainte globale (souvent évité via verrous explicites ou Serializable).
Lecture d’états financiers/rapports: RR/Serializable. Fort trafic d’updates: RC avec validations applicatives et verrous explicites ciblés.
#Bonnes pratiques
- Rejouer en cas d’échec sérialisable: sous Serializable, des conflits légitimes entraînent des erreurs; implémentez des retries bornés.
- Idempotence: rendez les opérations sûres à rejouer (clés uniques naturelles/synthétiques,
INSERT ... ON CONFLICT DO NOTHING/UPDATE
). - Petite surface: gardez les transactions courtes pour limiter la contention; évitez les appels réseau au milieu.
- Outbox/Inbox: pour des messages/events consistants avec la BD, utilisez un pattern outbox (écrire l’événement dans la même transaction, puis publier de manière fiable).
#Cas classique: write‑skew (invariant brisé)
Invariant métier: « au moins une personne de garde ». Deux utilisateurs A et B décident de se retirer de la garde simultanément.
1-- Table des gardes2create table if not exists garde(personne text primary key, de_garde boolean);3insert into garde(personne, de_garde) values ('A', true) on conflict(personne) do nothing;4insert into garde(personne, de_garde) values ('B', true) on conflict(personne) do nothing;
Sous isolation snapshot (RR/SSI), le scénario suivant peut briser l’invariant sans verrou explicite:
Session 1:
1begin;2-- voit 2 en garde3select count(*) from garde where de_garde = true; -- 24update garde set de_garde = false where personne = 'A';5-- commit plus tard
Session 2 (en parallèle):
1begin;2select count(*) from garde where de_garde = true; -- 2 (snapshot)3update garde set de_garde = false where personne = 'B';4commit;
Puis Session 1 commit → plus personne de garde. Correction:
- Verrou explicite sur la ligne « sentinelle » ou sur l’ensemble concerné (SELECT … FOR UPDATE), puis re‑vérifier l’invariant.
- Ou passer en
SERIALIZABLE
et gérer les rollbacks/retry.
Exemple avec verrou:
1begin;2-- verrouiller les lignes participant à l’invariant3select * from garde where de_garde = true for update;4-- revérifier5select count(*) from garde where de_garde = true; -- encore 26update garde set de_garde = false where personne = 'A';7commit;
#Diagramme: write‑skew (2 sessions)
#Correction (verrou / sérialisation)
#Exercice: lecture non répétable
- Session A:
begin; select balance from accounts where id=1;
- Session B:
begin; update accounts set balance=balance+10 where id=1; commit;
- Session A:
select balance from accounts where id=1;
→ valeur différente en RC.