C'est quoi une transaction ACID

Les transactions d'une base de données relationnelles sont ACID ce qui garantit la cohérence des données. Avec l'arrivée du monde NoSQL, on a souvent introduit le concept de BASE (Basically Available, Soft state, Eventually consistent). Cette logique est associée à la nature distribuée de ces systèmes. Il est plus complexe de conserver un état cohérent des données dès lors que l'on réplique et distribue la données.

Pour autant, cette garantie est ancrée fortement dans les habitudes des développeurs et l'usage de plus en plus important des bases NoSQL a mis en évidence que cette garantie est complexe à maintenir. De ce fait, on voit de plus en plus l'arrivée des transactions ACID dans le monde NoSQL.

Ici je vais refaire un point sur ce que ACID veut dire, et surtout expliquer les garanties apportées par cette logique.

C'est quoi une transaction ACID

Pour rappel, ACID veut dire:

- Atomique - Chaque transaction est exécutée correctement ou le processus s'arrête et la base de données revient à l'état précédant le début de la transaction. Cela garantit que toutes les données de la base sont valides.
- Cohérente - Une transaction traitée ne mettra jamais en péril l'intégrité structurelle de la base de données.
- Isolées - Les transactions ne peuvent pas compromettre l'intégrité d'autres transactions en interagissant avec elles alors qu'elles sont encore en cours.
- Durable - Les données relatives à la transaction achevée persistent même en cas de panne de réseau ou d'électricité. L'échec d'une transaction n'a pas d'incidence sur les données manipulées.

Trois de ces principes sont relativement simples à appréhender: Atomique, Cohérente, Durable. Si une transaction est validée (commit), alors l'ensemble des mutations le sont, en respect des contraintes d'intégrités et référentielles, et sans risque en cas de défaillance du système.

Pour l'isolation, c'est un peu plus complexe! En théorie, aucune transaction ne peut impacter une autre, mais dans la réalité ce n'est pas le cas.

source: https://jepsen.io/consistency

Ce modèle explique plus en détails les différents niveaux d'isolation qui sont possibles avec les bases de données. Toutes ne proposent l'ensemble, mais elle est respectera au moins un de ces niveaux. Les couleurs sont utilisées pour montrer les effets sur la base de données.

Donc en bleu nous aurons les bases de données disponibles "quoi qu'il en soit". Cela veut dire que les données lues ne sont pas forcément à jour, mais la base fournira une réponse. En jaune, nous trouvons celles qui sont capables de fournir une réponse si, et seulement si, le client reste connecté au même serveur. Enfin en rose, nous trouvons les systèmes qui pourront se trouver indisponibles afin de garantir que la donnée demandée soit dans la dernière version validée.

Ça se passe comment pour ma base?

Ce qu'il faut comprendre, c'est que ces différents niveaux ne proposent pas les mêmes garanties du tout! En effet, on peut constater que le niveau Read Commited fournira une réponse même si cette dernière n'est pas correcte.

De plus, il a été démontré que ces niveaux exposent à des risques sur les cohérences des transactions. Ce que l'on pense que la base de données fait et ce qu'elle fait réellement ne sont pas forcément des fonctionnements identiques.

Voici une présentation des risques transactionnels sur les systèmes les plus courants de RDBMS:

Attention! Ici nous parlons des niveaux d'isolation par défaut. Le niveau Serializable est disponible sur l'ensemble des moteurs présentés, mais c'est au DBA ou aux développeurs de le forcer.

Ce que l'on peut constater, c'est que les bases relationnelles les plus répandues offrent, par défaut, une garantie ACID un peu laxiste au regard des risques. On peut trouver une explication détaillée ici.

On peut trouver des exemples d'exploitations possibles ici.

De ces différentes lectures, on comprend que finalement les bases de données fonctionnent sur des modèles parfois permissifs pour obtenir de meilleures performances. Sur le modèle ACID, on comprend donc que ACD sont toujours garantis, mais que le niveau d'isolation peut avoir un impact fort sur l'application ou les systèmes au sens large et provoquer une incohérence des données.

CockroachDB fonctionne sur un autre modèle. Les transactions sont Serializable par défaut et il n'existe pas d'autres niveaux d'isolations. La perte de performance est compensée par un système de stockage différent permettant de limiter l'impact de ces garanties.

Conclusion

On l'aura compris, toutes les bases de données ne proposent pas les mêmes garanties sur les transactions par défaut. Cette logique associée au niveau d'isolation des transactions est, malheureusement, encore trop méconnue.

CockroachDB apporte une garantie maximale tout en garantissant les performances via une architecture particulière. De plus, il est possible de rendre la base de données distribuée géographiquement (plusieurs DC et même sur plusieurs continents si besoin), afin de maximiser la disponibilité.

Dans un prochain article, j'expliquerai plus en détail les risques et comment ils peuvent se matérialiser.