La seconde session fait d'abord une simple sélection, sans poser de verrou. Pas de problème, la requête passe.
Ah ? La requête passe ? Et c'est normal ? Et le verrou exclusif alors ?
Oui, c'est normal et c'est important de comprendre pourquoi.
En fait, lorsqu'une session démarre une transaction, elle prend en quelque sorte une photo des tables dans leur état actuel (les
modifications non commitées n'étant pas visibles). La transaction va alors travailler sur la base de cette photo, tant qu'on ne lui
demande pas d'aller vérifier que les données n'ont pas changé. Donc le SELECT ne voit pas les changements, et ne se heurte
pas au verrou, puisque celui-ci est posé sur les lignes de la table, et non pas sur la photo de cette table que détient la session.
Et comment fait-on pour demander à la session d'actualiser sa photo ?
On lui demande de poser un verrou ! Lorsqu'une session pose un verrou sur une table, elle est obligée de travailler vraiment avec
la table, et pas sur sa photo. Elle va donc aller chercher les dernières infos disponibles, et actualiser sa photo par la même
occasion.
On le voit bien avec la seconde requête, qui tente de poser un verrou partagé (qui vise donc uniquement la lecture). Elle va
d'abord chercher les lignes les plus à jour et tombe sur le verrou posé par la première session ; elle se retrouve alors bloquée
jusqu'à ce que la première session ôte le verrou exclusif.
Session 1 :
Code : SQL
COMMIT;
En committant les changements de la session 1, le verrou exclusif posé par la requête de modification est relâché. La session 2
est donc libre de poser à son tour un verrou partagé.
On peut également essayer la même manœuvre, avec cette fois-ci un UPDATE plutôt qu'un SELECT ... LOCK IN SHARE
MODE (donc une requête qui va tenter de poser un verrou exclusif plutôt qu'un verrou partagé).
Session 1 :
Code : SQL
START TRANSACTION;
UPDATE Adoption SET paye = 0
WHERE client_id = 11;
Session 2 :
Code : SQL
START TRANSACTION;
UPDATE Adoption SET paye = 1
WHERE animal_id = 32; -- l'animal 32 a été adopté par le client 11
Comme prévu, la seconde session est bloquée, jusqu'à ce que la première session termine sa transaction. Validez la transaction
de la première session, puis de la seconde. Le comportement sera le même si la deuxième session fait un DELETE sur les lignes
verrouillées, ou un SELECT ... FOR UPDATE.
Verrou posé par une requête d'insertion
Session 1 :
Partie 5 : Sécuriser et automatiser ses actions
244/414
www.openclassrooms.com
Ah ? La requête passe ? Et c'est normal ? Et le verrou exclusif alors ?
Oui, c'est normal et c'est important de comprendre pourquoi.
En fait, lorsqu'une session démarre une transaction, elle prend en quelque sorte une photo des tables dans leur état actuel (les
modifications non commitées n'étant pas visibles). La transaction va alors travailler sur la base de cette photo, tant qu'on ne lui
demande pas d'aller vérifier que les données n'ont pas changé. Donc le SELECT ne voit pas les changements, et ne se heurte
pas au verrou, puisque celui-ci est posé sur les lignes de la table, et non pas sur la photo de cette table que détient la session.
Et comment fait-on pour demander à la session d'actualiser sa photo ?
On lui demande de poser un verrou ! Lorsqu'une session pose un verrou sur une table, elle est obligée de travailler vraiment avec
la table, et pas sur sa photo. Elle va donc aller chercher les dernières infos disponibles, et actualiser sa photo par la même
occasion.
On le voit bien avec la seconde requête, qui tente de poser un verrou partagé (qui vise donc uniquement la lecture). Elle va
d'abord chercher les lignes les plus à jour et tombe sur le verrou posé par la première session ; elle se retrouve alors bloquée
jusqu'à ce que la première session ôte le verrou exclusif.
Session 1 :
Code : SQL
COMMIT;
En committant les changements de la session 1, le verrou exclusif posé par la requête de modification est relâché. La session 2
est donc libre de poser à son tour un verrou partagé.
On peut également essayer la même manœuvre, avec cette fois-ci un UPDATE plutôt qu'un SELECT ... LOCK IN SHARE
MODE (donc une requête qui va tenter de poser un verrou exclusif plutôt qu'un verrou partagé).
Session 1 :
Code : SQL
START TRANSACTION;
UPDATE Adoption SET paye = 0
WHERE client_id = 11;
Session 2 :
Code : SQL
START TRANSACTION;
UPDATE Adoption SET paye = 1
WHERE animal_id = 32; -- l'animal 32 a été adopté par le client 11
Comme prévu, la seconde session est bloquée, jusqu'à ce que la première session termine sa transaction. Validez la transaction
de la première session, puis de la seconde. Le comportement sera le même si la deuxième session fait un DELETE sur les lignes
verrouillées, ou un SELECT ... FOR UPDATE.
Verrou posé par une requête d'insertion
Session 1 :
Partie 5 : Sécuriser et automatiser ses actions
244/414
www.openclassrooms.com
