Verrous de lecture SELECT ... FOR UPDATE et SELECT ... LOCK IN SHARE MODE
<<<
Verrou de clé suivante : éviter le problème des lignes fantômes Un exemple de lecture cohérente avec InnoDB
>>>

16.11 Modèle de transactions et verrouillage InnoDB
16 Tables InnoDB
 Manuel de Référence MySQL 4.1 : Version Française

InnoDB et AUTOCOMMIT
InnoDB et SET ... TRANSACTION ISOLATION LEVEL ...
Lecture cohérente non-bloquante
Verrous de lecture SELECT ... FOR UPDATE et SELECT ... LOCK IN SHARE MODE
->Verrou de clé suivante : éviter le problème des lignes fantômes
Un exemple de lecture cohérente avec InnoDB
Les verrous posés par différentes requêtes SQL avec InnoDB
Quand est-ce que MySQL valide ou annule implicitement une transaction?
Détection des blocages et annulation
Comment gérer les blocages de verrous?

16.11.5 Verrou de clé suivante : éviter le problème des lignes fantômes

Avec le verrouillage de ligne, InnoDB utilise un algorithme appelé le verrouillage de la clé suivante. InnoDB fait un verrouillage de telle sorte que lorsqu'il fait une recherche ou un scan d'index, il pose des verrous partagés ou exclusifs sur les lignes d'index qu'il rencontre. Par conséquent, les verrous de lignes sont plus exactement appelés des verrous d'index.

Les verrous que InnoDB posent affectent aussi l'espace qui le sépare de la ligne suivante. Si un utilisateur a un verrou partagé ou exclusif sur une ligne L dans un index, alors un autre utilisateur ne peut faire d'insertion immédiatement avant la ligne L, dans l'ordre de l'index. Ce verrouillage est fait pour éviter le problème de la ligne fantôme. Supposons que je veuille lire et verrouiller tous les enfants ayant un identifiant supérieur à 100 dans la table CHILD , puis modifier certains champs des lignes ainsi identifiées :


SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;
Supposons qu'il y ait un index sur la table CHILD , sur la colonne ID . Notre requête va scanner l'index à partir de la première ligne où ID est plus grand que 100. Maintenant, si le verrou posé sur les lignes d'index n'empêche pas l'utilisation des intervalles entre les lignes d'index, un nouvel enfant peut être inséré dans la table durant la lecture. Et maintenant, si ma transaction exécute la commande :

SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;
je vais trouver un nouvel enfant dans le résultat de ma requête. Ceci va à l'encontre du principe d'isolation des transactions : une transaction doit être capable de s'exécuter sans que les lectures soient affectées durant ce temps. Si vous considérons un intervalle de données, alors la nouvelle ligne 'fantôme' va casser le principe d'isolation.Lorsque InnoDB scanne un index, il va aussi verrouille l'espace après la dernière ligne de l'index. C'est ce qui est arrivé dans l'exemple ci-dessus : le verrou posé par InnoDB va éviter qu'une insertion n'intervienne dans la table où ID serait plus grand que 100.

Vous pouvez utiliser le verrouillage de la clé suivant pour implémenter des vérifications d'unicité dans votre application : si vous lisez des données en mode partagé, et que vous ne voyez pas de duplicata de la ligne que vous allez insérer, alors vous pouvez l'insérer sans problème, en sachant que le verrou de clé suivante va vous garantir que durant ce temps, personne ne pourra insérer de ligne, qui déboucherait sur un duplicata de la votre. Le verrou de clé suivante permet de verrouiller aussi la non-existence de ligne dans votre table.

<< Verrou de clé suivante : éviter le problème des lignes fantômes >>
Verrous de lecture SELECT ... FOR UPDATE et SELECT ... LOCK IN SHARE MODE Modèle de transactions et verrouillage InnoDB Un exemple de lecture cohérente avec InnoDB