Une transaction ACID est un groupe d’opérations de base de données validé comme une seule unité — atomique, cohérente, isolée et durable. L’idée précède l’acronyme : Jim Gray a défini les garanties en 1981, Härder et Reuter les ont baptisées ACID en 1983, et quarante ans plus tard, cela reste le contrat qui vous permet de déplacer de l’argent dans un logiciel sans, de temps en temps, en inventer ou en détruire une partie.
Points clés
| Question | Réponse |
|---|---|
| Les quatre lettres | Atomique (tout-ou-rien) · Cohérente (les règles tiennent) · Isolée (sans interférence) · Durable (survit aux crashs) |
| Exemple canonique | Le virement bancaire : débit + crédit validés ensemble ou pas du tout |
| Le curseur | Les niveaux d’isolation — la performance échangée contre des anomalies de lecture |
| Le rival | BASE / cohérence à terme — la disponibilité échangée contre de l’obsolescence |
| La réalité moderne | Les bases documentaires font aussi de l’ACID ; les petites lignes portent sur la portée |
Comment fonctionnent les transactions ACID en SQL (exemple de virement bancaire)
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 'alice';
UPDATE accounts SET balance = balance + 100 WHERE id = 'bob';
-- Crash ou erreur entre les deux UPDATE ? Le moteur fait un rollback :
-- ROLLBACK; → les deux modifications disparaissent ; l'argent ne peut pas s'évaporer
COMMIT; -- ou les deux deviennent permanentes, atomiquement, durablement
Le code applicatif rencontre les mêmes garanties en plus petits paquets — des opérations atomiques sur les champs qui mettent fin à la course read-modify-write, et des lots validés ensemble :
// JavaScript / Node.js — Back4app JS SDK
// Atomicity where apps actually need it
counter.increment('sold', 1); // atomic single-field update — no
await counter.save(); // read-modify-write race possible
// All-or-nothing batch: both rows commit, or neither does
await Parse.Object.saveAll([debitEntry, creditEntry], { transaction: true }); // Flutter / Dart — Back4app Flutter SDK
// Atomicity where apps actually need it
counter.setIncrement('sold', 1); // atomic single-field update — no
await counter.save(); // read-modify-write race possible
// Batches group writes; atomic counters remove the classic race
await ParseObject.saveAll([debitEntry, creditEntry]); // iOS / Swift — Back4app Swift SDK
// Atomicity where apps actually need it
var updated = counter
updated.sold = (updated.sold ?? 0) + 1
// Prefer the atomic operation over read-modify-write:
let op = counter.operation.increment("sold", by: 1)
op.save { result in
if case .success = result { print("atomic increment committed") }
} // Android / Kotlin — Back4app Android SDK
// Atomicity where apps actually need it
counter.increment("sold") // atomic single-field update — no
counter.saveInBackground() // read-modify-write race possible
// Batches group writes; atomic counters remove the classic race
ParseObject.saveAllInBackground(listOf(debitEntry, creditEntry)) Le cycle de vie d’une transaction : BEGIN, COMMIT et ROLLBACK
Les quatre propriétés, chacune par ce qui casse sans elle : l’atomicité — sans elle, des écritures partielles (le virement débité-mais-jamais-crédité). La cohérence — sans elle, des états validés qui violent vos propres règles (stock négatif, références orphelines). L’isolation — sans elle, les transactions concurrentes lisent le travail à moitié fini les unes des autres. La durabilité — sans elle, des données « validées » qu’un crash désécrit en silence. Sous le capot, trois mécanismes les assurent : des journaux d’annulation pour le rollback, le write-ahead logging pour survivre aux crashs, et le verrouillage ou MVCC pour la concurrence.
Niveaux d’isolation vs. anomalies de lecture
La matrice que les résultats de recherche n’assemblent jamais — quel niveau arrête quelle anomalie :
| Niveau | Lecture sale | Lecture non répétable | Lecture fantôme | Coût |
|---|---|---|---|---|
| Read uncommitted | possible | possible | possible | le plus bas |
| Read committed | empêchée | possible | possible | bas |
| Repeatable read | empêchée | empêchée | possible | moyen |
| Serializable | empêchée | empêchée | empêchée | le plus élevé |
Traduction : une lecture sale (dirty read) voit du travail non validé ; une lecture non répétable obtient des réponses différentes en demandant deux fois ; un fantôme voit des lignes apparaître en cours de transaction. La plupart des moteurs modernes adoptent par défaut un comportement snapshot basé sur MVCC — chaque transaction lit un instantané cohérent pendant que les écrivains avancent — et c’est pourquoi « les lecteurs ne bloquent pas les écrivains » est devenu la norme plutôt que l’exception.
ACID vs. BASE — et l’homonymie de la cohérence
| Dimension | ACID | BASE |
|---|---|---|
| Optimise pour | La correction par transaction | La disponibilité à l’échelle |
| Cohérence | Immédiate, préservant les règles | À terme |
| Habitat naturel | Argent, inventaire, réservations | Feeds, compteurs, caches |
| Posture de mise à l’échelle | Limitée par la coordination | Horizontale par conception |
| Mode de dégradation | Plus lent sous contention | Lectures temporairement obsolètes |
Une seule désambiguïsation porte toute cette comparaison : le C d’ACID et le C de CAP sont deux mots différents qui partagent la même lettre. La cohérence ACID signifie que chaque transaction préserve les règles que vous avez déclarées. La cohérence CAP signifie que tous les nœuds sont d’accord à l’instant même. Une base de données mono-nœud est pleinement ACID sans que CAP entre dans la pièce ; un système distribué choisit son trade-off CAP et ses garanties transactionnelles séparément.
Qui garantit quoi
| Famille de moteurs | Situation vis-à-vis d’ACID |
|---|---|
| PostgreSQL | ACID complet, MVCC, serializable disponible |
| MySQL | ACID complet avec InnoDB — le choix du moteur de stockage compte |
| SQLite | ACID complet, écrivain unique, mode WAL |
| MongoDB | Atomicité mono-document toujours ; transactions multi-documents depuis la 4.0 (2018), isolation snapshot |
| Moteurs SQL distribués | ACID via réplication par consensus — serializable au prix du réseau |
| Stores wide-column / à cohérence à terme | Ajustable, partiel — BASE par conception |
Les transactions distribuées méritent leur note de bas de page honnête : le commit à deux phases (two-phase commit) achète l’atomicité entre nœuds au prix de la latence et d’un coordinateur bloquant, ce qui explique pourquoi les architectures microservices préfèrent de plus en plus les sagas — des séquences de transactions locales avec des rollbacks compensatoires, échangeant la cohérence immédiate contre la disponibilité. Si un workflow ne tolère réellement pas la compensation, c’est la preuve qu’il a sa place dans une seule base de données, pas réparti sur plusieurs.
Cas d’usage courants
- Mouvements d’argent. Virements, paiements sortants, grands livres — le cas canonique, et toujours le plus clair.
- Inventaire et réservation. Décrémenter le stock et confirmer la commande ensemble, ou regarder deux clients acheter le dernier siège.
- Invariants multi-lignes. Commande + lignes de commande, compte + entrée d’audit — des enregistrements qui ne sont valides que nés ensemble.
- Des compteurs bien faits. Les incréments atomiques — la plus petite dose utile d’ACID — mettent fin à la course read-modify-write sans transactions complètes.
- Le complément à cohérence à terme. Feeds, likes, analytics : explicitement routés à l’écart du coût transactionnel, à dessein.
Faut-il de l’ACID ? Matrice de décision
| Exigez des transactions complètes quand… | La cohérence à terme suffit quand… |
|---|---|
| De l’argent ou une propriété change de mains | Un compteur obsolète ne coûte rien |
| Des écritures partielles créent des états invalides | Chaque écriture est valide indépendamment |
| Les régulateurs réclameront l’invariant | La donnée est dérivée et reconstructible |
| Deux lignes doivent concorder, toujours | Converger plus tard est une UX acceptable |
| Survendre, c’est un procès | Surcompter, c’est un haussement d’épaules |
Le métier, c’est le routage par écriture : le checkout utilise des transactions, le compteur de vues utilise un incrément atomique, le feed tolère une seconde de dérive — une seule application, trois tarifs pour la cohérence.
Limites et trade-offs
- La coordination est le centre de coûts. Les verrous se disputent, les synchronisations du WAL frappent le disque, les retries en serializable avortent — la correction a une facture en débit, et c’est toute la raison d’être de BASE.
- Les niveaux d’isolation sont une valeur par défaut piégée. La plupart des moteurs ne sont pas en serializable par défaut ; connaissez votre niveau, sinon les anomalies que vous croyiez impossibles sont seulement improbables.
- Les transactions longues sentent mauvais. Tenir des verrous pendant le temps de réflexion de l’utilisateur ou des appels réseau transforme les garanties en contention ; gardez les transactions courtes et décisives.
- L’ACID distribué est coûteux par nature. Des tours de consensus à chaque commit — payez-le là où les invariants l’exigent, pas partout par réflexe.
- ACID ne peut pas valider vos règles à votre place. La cohérence préserve les contraintes déclarées ; les règles métier jamais encodées ne sont, fidèlement, pas appliquées.
Les transactions ACID sur Back4app
Back4app est une plateforme open-source de Backend as a Service (BaaS) qui combine une base de données gérée, des API REST et GraphQL générées automatiquement, l’authentification, le stockage de fichiers et des fonctions serverless avec Cloud Code. Sa boîte à outils transactionnelle colle à la façon dont les apps consomment réellement ACID : chaque écriture d’un objet unique est atomique sur le moteur documentaire sous-jacent, les incréments atomiques et opérations sur tableaux mettent fin aux courses classiques sur les compteurs (les onglets de code ci-dessus), les enregistrements par lot regroupent les écritures, et les invariants en plusieurs étapes ont leur place dans Cloud Code — validés et exécutés côté serveur, où un trigger beforeSave peut refuser toute écriture qui enfreindrait les règles. La matrice de décision est intégrée : une atomicité bon marché par défaut, la coordination complète là où vous la demandez.
Questions fréquentes
Que signifie ACID ?
Atomicité, Cohérence, Isolation, Durabilité — les quatre garanties qu'une transaction de base de données doit offrir pour que les données restent correctes malgré les erreurs, les crashs et les utilisateurs concurrents. Jim Gray a défini les propriétés fondamentales en 1981 ; Theo Härder et Andreas Reuter ont forgé l'acronyme dans leur article de 1983 sur la reprise orientée transactions.
Qu'est-ce qu'une transaction ACID, en termes simples ?
Un groupe de lectures et d'écritures exécuté comme une unité tout-ou-rien. Soit chaque opération est validée et devient permanente, soit chaque opération est annulée comme si rien ne s'était passé. L'exemple canonique est le virement : débiter un compte, créditer un autre — un crash entre les deux ne doit jamais laisser l'argent débité mais non crédité.
Que sont les niveaux d'isolation ?
Le curseur qui échange de la performance contre de la protection quand les transactions s'exécutent en parallèle. Le standard SQL en définit quatre — read uncommitted, read committed, repeatable read, serializable — chacun empêchant davantage d'anomalies (lectures sales, lectures non répétables, fantômes) à un coût plus élevé. En pratique, la plupart des moteurs modernes utilisent par défaut une isolation de type snapshot via MVCC, où les lecteurs voient un instantané cohérent et ne bloquent jamais les écrivains.
Quelle est la différence entre ACID et BASE ?
Deux réponses au coût de la correction. ACID paie en coordination pour garantir que chaque transaction voit et laisse un état valide. BASE — Basically Available, Soft state, Eventually consistent — paie en obsolescence temporaire pour rester disponible et monter en charge horizontalement. Aucun n'est supérieur ; ils tarifent la cohérence différemment, et les systèmes réels les mélangent selon la charge de travail.
La cohérence d'ACID est-elle la même que celle du théorème CAP ?
Non — et les confondre est la confusion la plus courante sur ce sujet. La cohérence ACID signifie que chaque transaction préserve les règles déclarées : les contraintes tiennent, les invariants survivent. La cohérence CAP signifie que chaque nœud d'un système distribué voit les mêmes données au même moment. Une base de données mono-nœud peut être pleinement ACID sans que CAP ait quoi que ce soit à en dire.
Les bases de données NoSQL sont-elles conformes à ACID ?
De plus en plus, avec des petites lignes. Les bases documentaires ont toujours rendu atomiques les écritures sur un seul document — ce qui, combiné à l'imbrication des données liées, couvre la plupart des besoins d'une app. Les transactions ACID multi-documents sont arrivées dans MongoDB 4.0 (2018) avec une isolation snapshot, à un coût de performance réel. La vieille affirmation « NoSQL veut dire pas de transactions » est désormais simplement dépassée ; la préférence de conception pour modéliser autour de l'atomicité mono-document, elle, ne l'est pas.
Comment les bases de données implémentent-elles réellement ACID ?
Trois mécanismes portent la charge : les informations d'annulation rendent le rollback possible (atomicité) ; le write-ahead logging — les modifications enregistrées dans un journal durable avant d'être appliquées — survit aux crashs (durabilité) ; et le verrouillage ou MVCC tient les transactions concurrentes à l'écart les unes des autres (isolation). La cohérence en est le résultat : des contraintes vérifiées sous la protection des trois autres.
Quand la cohérence à terme suffit-elle ?
Quand une brève fenêtre d'obsolescence ne coûte rien : nombre de likes, compteurs de vues, fils d'activité, analytics, caches, recommandations produit. Quand elle ne suffit pas : l'argent, un inventaire qui peut être survendu, la réservation de sièges et de billets, tout ce qui est réglementé. La compétence d'ingénierie n'est pas de choisir un camp, mais de router chaque écriture vers la garantie dont elle a réellement besoin.