220
Chapitre 7. Transactions et verrous
Ces niveaux d’isolation permettent de choisir un équilibre entre la cohérence des
données et la concurrence d’accès : plus la cohérence transactionnelle est maintenue par un verrouillage fort, plus les données sont isolées des autres transactions, et
donc moins la concurrence d’accès simultanée entre sessions est possible.
Le niveau d’isolation peut être changé pour la session à l’aide de l’instruction SET
TRANCATION ISOLATION LEVEL comme nous le verrons ci-après. Il peut aussi être configuré dans une même requête, table par table, à l’aide d’un indicateur de table, tout
comme on peut choisir une granularité de verrou :
SELECT * FROM Person.Contact WITH (READUNCOMMITTED);
-- ou
SELECT * FROM Person.Contact WITH (NOLOCK);
Les deux syntaxes précédentes sont strictement équivalentes. NOLOCK est simplement un alias propre à SQL Server pour indiquer un niveau READ UNCOMMITTED. Mais
voyons ces niveaux.
Le niveau d’isolation READ UNCOMMITTED est le niveau le plus permissif, posant le
moins de verrou, et permettant donc l’apparition du plus grand nombre d’erreurs
transactionnelles. Dans ce niveau, les lectures sales (dirty reads) sont possibles : une
transaction peut lire des lignes qui sont en train d’être modifiées par une autre transaction, ou modifier des lignes en cours de lecture. L’extraction de données non validées (« sales ») est donc possible. Dans ce niveau, SQL Server continue à poser des
verrous exclusifs (X) lors de modifications : il est toujours impossible d’écrire en
même temps les mêmes lignes. Par contre, en lecture, aucun verrou n’est posé. Seul
un verrou de schéma (Sch-S) est maintenu, empêchant la modification de la structure des tables lues. De même, les verrous exclusifs ne sont pas honorés par la lecture.
Ce niveau est donc très favorable aux performances, en diminuant les opérations de
verrouillage, et les attentes de libération de verrous.
Vous entendrez certainement des mises en garde contre le niveau d’isolation READ
UNCOMMITTED. Les lectures sales inquiètent certaines personnes. Dans la pratique,
pour des générations de rapport, de l’extraction de données ou du simple affichage, il
est rare de se préoccuper d’obtenir une ligne validée ou non. À un centième de
secondes près, vous obtenez une valeur différente, quelle importance ? Compte tenu
du gain de performances apporté par ce mode, nous ne pouvons que vous le conseiller pour des requêtes de lecture. La vraie contre-indication se présente dans un
environnement où des transactions modifient plusieurs lignes en rapport les unes
avec les autres, dans des tables différentes ou dans la même table. Exemple classique,
si vous gérez une application bancaire et que vous effectuez par SELECT un total des
avoirs d’un client, vous risquez, en niveau READ UNCOMMITTED, de lire des totaux erronés si en même temps une transaction retire un montant d’un compte courant pour
le poser sur un compte d’épargne. Si le SELECT intervient lorsque la ligne est supprimée du compte courant, mais pas encore ajoutée au compte d’épargne, le total sera
inférieur au crédit du client. Dans ce genre de cas, le niveau d’isolation SNAPSHOT
peut permettre une plus grande concurrence, sans ralentir les requêtes par des attentes de verrous. Lorsque ce risque n’est pas présent, un SET TRANSACTION ISOLATION
Chapitre 7. Transactions et verrous
Ces niveaux d’isolation permettent de choisir un équilibre entre la cohérence des
données et la concurrence d’accès : plus la cohérence transactionnelle est maintenue par un verrouillage fort, plus les données sont isolées des autres transactions, et
donc moins la concurrence d’accès simultanée entre sessions est possible.
Le niveau d’isolation peut être changé pour la session à l’aide de l’instruction SET
TRANCATION ISOLATION LEVEL comme nous le verrons ci-après. Il peut aussi être configuré dans une même requête, table par table, à l’aide d’un indicateur de table, tout
comme on peut choisir une granularité de verrou :
SELECT * FROM Person.Contact WITH (READUNCOMMITTED);
-- ou
SELECT * FROM Person.Contact WITH (NOLOCK);
Les deux syntaxes précédentes sont strictement équivalentes. NOLOCK est simplement un alias propre à SQL Server pour indiquer un niveau READ UNCOMMITTED. Mais
voyons ces niveaux.
Le niveau d’isolation READ UNCOMMITTED est le niveau le plus permissif, posant le
moins de verrou, et permettant donc l’apparition du plus grand nombre d’erreurs
transactionnelles. Dans ce niveau, les lectures sales (dirty reads) sont possibles : une
transaction peut lire des lignes qui sont en train d’être modifiées par une autre transaction, ou modifier des lignes en cours de lecture. L’extraction de données non validées (« sales ») est donc possible. Dans ce niveau, SQL Server continue à poser des
verrous exclusifs (X) lors de modifications : il est toujours impossible d’écrire en
même temps les mêmes lignes. Par contre, en lecture, aucun verrou n’est posé. Seul
un verrou de schéma (Sch-S) est maintenu, empêchant la modification de la structure des tables lues. De même, les verrous exclusifs ne sont pas honorés par la lecture.
Ce niveau est donc très favorable aux performances, en diminuant les opérations de
verrouillage, et les attentes de libération de verrous.
Vous entendrez certainement des mises en garde contre le niveau d’isolation READ
UNCOMMITTED. Les lectures sales inquiètent certaines personnes. Dans la pratique,
pour des générations de rapport, de l’extraction de données ou du simple affichage, il
est rare de se préoccuper d’obtenir une ligne validée ou non. À un centième de
secondes près, vous obtenez une valeur différente, quelle importance ? Compte tenu
du gain de performances apporté par ce mode, nous ne pouvons que vous le conseiller pour des requêtes de lecture. La vraie contre-indication se présente dans un
environnement où des transactions modifient plusieurs lignes en rapport les unes
avec les autres, dans des tables différentes ou dans la même table. Exemple classique,
si vous gérez une application bancaire et que vous effectuez par SELECT un total des
avoirs d’un client, vous risquez, en niveau READ UNCOMMITTED, de lire des totaux erronés si en même temps une transaction retire un montant d’un compte courant pour
le poser sur un compte d’épargne. Si le SELECT intervient lorsque la ligne est supprimée du compte courant, mais pas encore ajoutée au compte d’épargne, le total sera
inférieur au crédit du client. Dans ce genre de cas, le niveau d’isolation SNAPSHOT
peut permettre une plus grande concurrence, sans ralentir les requêtes par des attentes de verrous. Lorsque ce risque n’est pas présent, un SET TRANSACTION ISOLATION
