12.2. Isolation des transactions

Le standard SQL d�finit quatre niveaux d'isolation de transaction pour emp�cher trois ph�nom�nes de se produire lors de transactions concurrentes. Ces ph�nom�nes ind�sirables sont :

lecture sale

Une transaction lit des donn�es �crites par une transaction concurrente non valid�e.

lecture non reproductible

Une transaction relit des donn�es qu'elle a lu pr�c�demment et trouve que les donn�es ont �t� modifi�es par une autre transaction (valid�e depuis la lecture initiale).

lecture fant�me

Une transaction r�-ex�cute une requ�te renvoyant un ensemble de lignes satisfaisant une condition de recherche et trouve que l'ensemble des lignes satisfaisant la condition a chang� du fait d'une autre transaction r�cemment valid�e.

Les quatre niveaux d'isolation de transaction et les comportements correspondants sont d�crits dans le Tableau 12-1.

Tableau 12-1. Niveaux d'isolation des transactions SQL

Niveau d'isolation Lecture sale Lecture non reproductible Lecture fant�me
Uncommited Read (en fran�ais, <<�Lecture de donn�es non valid�es�>>) Possible Possible Possible
Commited Read (en fran�ais, <<�Lecture de donn�es valid�es�>>) Impossible Possible Possible
Repeatable Read (en fran�ais, <<�Lecture r�p�t�e�>>) Impossible Impossible Possible
Serializable (en fran�ais, <<�S�rialisable�>>) Impossible Impossible Impossible

PostgreSQL offre les niveaux d'isolation de lecture valid�e et s�rialisable.

12.2.1. Niveau d'isolation Read committed (lecture des seules donn�es valid�es)

Read Commited est le niveau d'isolation par d�faut de PostgreSQL. Lorsqu'une transaction fonctionne avec ce niveau d'isolation, une requ�te SELECT voit uniquement les donn�es valid�es avant que la requ�te soit lanc�e ; elle ne voit jamais, lors de l'ex�cution de la requ�te, ni les donn�es non valid�es ni les modifications valid�es par les transactions concurrentes (n�anmoins, le SELECT voit les effets des pr�c�dentes mises � jour dans sa propre transaction, et ce m�me si elles ne sont pas valid�es). Dans les faits, une requ�te SELECT voit une image de la base de donn�es � l'instant o� la requ�te a �t� lanc�e. Notez que des commandes SELECT successives peuvent voir des donn�es diff�rentes, y compris si elles font partie de la m�me transaction, si d'autres transactions valident des modifications de donn�es pendant l'ex�cution du premier SELECT.

Les commandes UPDATE, DELETE et SELECT FOR UPDATE se comportent de la m�me fa�on que SELECT en ce qui concerne la recherche des lignes cibles : elles ne trouveront que les lignes cibles qui ont �t� valid�es avant le d�but de la commande. N�anmoins, une telle ligne cible pourrait avoir d�j� �t� mise � jour (ou supprim�e ou marqu�e pour mise � jour) par une autre transaction concurrente au moment o� elle est d�couverte. Dans ce cas, le processus de mise � jour attendra que la premi�re transaction soit valid�e ou annul�e (si elle est toujours en cours). Si la premi�re mise � jour est annul�e, alors ses effets sont ni�s et le deuxi�me processus peut ex�cuter la mise � jour des lignes originellement trouv�es. Si la premi�re mise � jour est valid�e, la deuxi�me mise � jour ignorera la ligne si la premi�re mise � jour l'a supprim�e, sinon elle essaiera d'appliquer son op�ration � la version mise � jour de la ligne. La condition de recherche de la commande (la clause WHERE) est r�-�valu�e pour savoir si la version mise � jour de la ligne correspond toujours � la condition de recherche. Dans ce cas, la deuxi�me mise � jour continue son op�ration, en commen�ant par la version mise � jour de la ligne.

� cause de la r�gle ci-dessus, une commande de mise � jour a la possibilit� de voir une image non coh�rente : elle peut voir les effets de commandes de mises � jour concurrentes affectant les m�mes lignes que celles qu'elle essaie de mettre � jour mais elle ne voit pas les effets de ces commandes sur les autres lignes de la base de donn�es. Ce comportement rend le mode de lecture valid�e non convenable pour les commandes qui impliquent des conditions de recherche complexes. N�anmoins, il est correct pour les cas simples. Par exemple, consid�rons la mise � jour de balances de banque avec des transactions comme

BEGIN;
UPDATE comptes SET balance = balance + 100.00 WHERE no_compte = 12345;
UPDATE comptes SET balance = balance - 100.00 WHERE no_compte = 7534;
COMMIT;

Si deux transactions comme celle-ci essaient de modifier en m�me temps la balance du compte 12345, nous voulons clairement que la deuxi�me transaction commence � partir de la version mise � jour de la ligne du compte. Comme chaque commande n'affecte qu'une ligne pr�d�termin�e, la laisser voir la version mise � jour de la ligne ne cr�e pas de soucis de coh�rence.

Comme dans le mode de lecture valid�e, chaque nouvelle commande commence avec une nouvelle image incluant toutes les transactions valid�es jusque l�, les commandes suivantes dans la transaction verront les effets de la transaction concurrente valid�e dans tous les cas. La probl�matique ici est de savoir si � l'int�rieur d'une m�me commande, nous avons ou non une vision totalement coh�rente de la base de donn�es.

L'isolation partielle de la transaction fournie par le mode de lecture valid�e est ad�quate pour de nombreuses applications et ce mode est rapide et simple � utiliser. N�anmoins, pour les applications r�alisant des requ�tes et mises � jour complexes, il pourrait �tre n�cessaire de garantir une vue plus coh�rente de la base de donn�es que ce que fournit le mode Read Commited.

12.2.2. Niveau d'isolation s�rialisable

Le niveau s�rialisable est le niveau d'isolation de transaction le plus strict. Ce niveau �mule l'ex�cution de la transaction en s�rie, comme si les transactions avaient �t� ex�cut�es l'une apr�s l'autre, en s�rie plut�t que parall�lement. N�anmoins, les applications utilisant ce niveau doivent �tre pr�par�es � tenter de nouveau les transactions suite aux �checs de la s�rialisation.

Quand une transaction est dans le niveau s�rialisable, une requ�te SELECT voit seulement les donn�es valid�es avant le d�but de la transaction ; elle ne voit jamais les donn�es non valid�es et les modifications valid�es lors de l'ex�cution de la transaction par des transactions concurrentes (n�anmoins, le SELECT voit bien les effets des mises � jour pr�c�dentes ex�cut�es � l'int�rieur de sa propre transaction m�me si elles ne sont pas encore valid�es). C'est diff�rent du niveau Read Commited dans la mesure o� SELECT voit une image du d�but de la transaction et non pas du d�but de la requ�te en cours � l'int�rieur de la transaction. Du coup, les commandes SELECT successives � l'int�rieur d'une m�me transaction voit toujours les m�mes donn�es.

Les commandes UPDATE, DELETE et SELECT FOR UPDATE se comportent de la m�me fa�on que SELECT en ce qui concerne la recherche de lignes cibles : elles trouveront seulement les lignes cibles qui ont �t� valid�es avant le d�but de la transaction. N�anmoins, une telle ligne cible pourrait avoir �t� mise � jour (ou supprim�e ou marqu�e pour mise � jour) par une autre transaction concurrente au moment o� elle est utilis�e. Dans ce cas, la transaction s�rialisable attendra que la premi�re transaction de mise � jour soit valid�e ou annul�e (si celle-ci est toujours en cours). Si la premi�re mise � jour est annul�e, les effets sont invers�s et la transaction s�rialisable peut continuer avec la mise � jour de la ligne trouv�e � l'origine. Mais si le processus de mise � jour est valid� (et que la ligne est mise � jour ou supprim�e, pas simplement s�lectionn�e en vue d'une mise � jour), alors la transaction s�rialisable sera annul�e avec le message

ERROR:  could not serialize access due to concurrent update

parce qu'une transaction s�rialisable ne peut pas modifier les lignes chang�es par d'autres transactions apr�s que la transaction s�rialisable ait commenc�.

Quand l'application re�oit ce message d'erreurs, elle devrait annuler la transaction actuelle et r�-essayer la transaction compl�te. La seconde fois, la transaction voit les modifications d�j� valid�es comme faisant partie de sa vue initiale de la base de donn�es, donc il n'y a pas de conflit logique en utilisant la nouvelle version de la ligne comme point de d�part pour la mise � jour de la nouvelle transaction.

Notez que seules les transactions de modifications ont besoin d'�tre tent�es de nouveau ; les transactions en lecture seule n'auront jamais de conflits de s�rialisation.

Le mode s�rialisable fournit une garantie rigoureuse que chaque transaction acc�de � une vue totalement coh�rente de la base de donn�es. N�anmoins, l'application doit �tre pr�te � tenter de nouvelles transactions lorsque des mises � jour concurrentes rendent impossibles de soutenir l'illusion d'une ex�cution en s�rie. Comme le co�t de re-lancement de transactions complexes pourrait �tre significatif, ce mode est seulement recommand� lors de mise � jour contenant une logique suffisamment complexe pour donner de mauvaises r�ponses dans le mode de lecture valid�e. Plus commun�ment, le mode s�rialisable est n�cessaire quand une transaction ex�cute plusieurs commandes successives qui doivent avoir des vues identiques de la base de donn�es.