SOS Fantômes !
Les systèmes de gestion de bases de données relationnelles sont connus pour leurs propriétés ACID. Le I signifie ISOLATION. De multiples transactions peuvent être gérées simultanément par un SGBDR. Le standard SQL définit plusieurs niveaux disolation fixant les règles régissant la concurrence entre ces transactions. Dans cet article nous allons nous intéresser au troisième niveau, le REPEATABLE READ. Ce niveau nautorise ni les lectures sales (dirty reads) ni les lectures non reproductibles (nonrepeatable read). En revanche, les lectures fantômes (phantom reads) sont autorisées. Cela signifie quen exécutant 2 fois la même requête dans une transaction, les données lues la première fois seront inchangées à la deuxième lecture. Mais cela ne signifie pas pour autant que le jeu de résultats obtenu lors des 2 exécutions sera identique. Des données supplémentaires ont pu modifier le deuxième jeu de résultats si elles ont été insérées par une autre autre transaction validée entre les 2 exécutions de la requête.
Démonstration avec PostgreSQL 9.6 :
Les ordres SELECT de la session 1 ont donné les mêmes résultats dans la première partie de la transaction et la deuxième. Les lectures sont reproductibles, ce qui êtait attendu. Il ny a pas non plus de lectures fantômes, ce qui ne létait pas. Lexplication est la même que dans le premier chapitre. Si les niveaux disolation reposaient sur le verrouillage dans PostgreSQL, lunique ligne présente au départ aurait été verrouillée après la première série de SELECT pour assurer les lectures reproductibles. Les résultats des deux "SELECT * FROM t1 WHERE c1 = 1" auraient donc été identiques alors que les résultats des autres SELECT auraient été différents dune exécution à lautre.
Mais PostgreSQL sappuie sur un mécanisme MVCC (multiversion concurrencty control), le principe est de présenter une vision adéquate de TOUTE la base. Les lectures fantômes et les lectures non reproductibles sont éliminées simultanément. Il est donc impossible davoir des lectures fantômes au niveau REPEATABLE READ avec PostgreSQL. A noter encore une fois que ce comportement est compatible avec le standard SQL. En effet, le standard impose de NE PAS avoir de lecture fantômes à partir du niveau SERIALIZABLE mais il nimpose pas davoir des lectures fantômes aux niveaux inférieurs comme le REPEATABLE READ.
Pas de lectures fantômes au niveau REPEATABLE READ, cela signifie-t-il que les niveaux disolation REPEATABLE READ et SERIALIZABLE sont équivalents avec PostgreSQL ? Pour atteindre le niveau SERIALIZABLE, les transactions exécutées en concurrence doivent pouvoir être exécutées séquentiellement en donnant les mêmes résultats. Si cest impossible on parle danomalie de sérialisation.
Démonstration, toujours avec PostgreSQL 9.6 :
Pas danomalie de sérialisation ! Il serait pourtant impossible dobtenir ces résultats en exécutant séquentiellement les transactions présentées dans les sessions 1 et 2. La transaction de la session 1 modifie la ligne lue dans la session 2 et la transaction de la session 2 modifie la ligne lue dans la session 1. Si la transaction de la session 1 est intégralement exécutée avant la transaction de la session 2 alors le "SELECT * FROM t1 WHERE c1 = 2" ne renverra aucune ligne. Et si cest la transaction de la session 2 qui est intégralement exécutée avant la transaction de la session 1 alors cest le "SELECT * FROM t1 WHERE c1 = 1" qui ne renverra aucune ligne.
Les niveaux REPEATABLE READ et SERIALIZATION ne sont donc PAS équivalents avec PostgreSQL, en tous cas en version 9.6. Le comportement observé est en fait valable depuis la version 9.1 donc cet article est pertinent pour toutes les versions supportées.
Quel est le comportement dOracle Database en ce qui concerne ce niveau disolation à présent ? Démonstration avec Oracle Database 11.2.0.2 :
Pas de niveau disolation REPEATABLE READ avec Oracle Database. Il faut directement passer au niveau SERIALIZABLE avec ce SGBD pour obtenir des lectures reproductibles.