LOCK [ TABLE ] table LOCK [ TABLE ] table IN [ ROW | ACCESS ] { SHARE | EXCLUSIVE } MODE LOCK [ TABLE ] table IN SHARE ROW EXCLUSIVE MODE |
nom d'une table existante à verrouiller.
Le mode lock est placé automatiquement sur les tables questionnées. Postgres libère automatiquement les verrous ACCESS SHARE une fois la clause effectuée. |
C'est le mode de verrouillage le moins restrictif qui entre en conflit seulement avec le mode ACCESS EXCLUSIVE. Son but est de protéger une table questionnée des clauses concurrentes ALTER TABLE, DROP TABLE et VACUUM sur la même table.
Automatiquement placé par n'importe quelle clause SELECT FOR UPDATE. |
Conflits avec les modes de verrouillage EXCLUSIVE et ACCESS EXCLUSIVE.
Automatiquement placé par n'importe quelle clause UPDATE, DELETE, INSERT. |
Conflits avec les modes SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE et ACCESS EXCLUSIVE. Signifie généralement qu'une transaction a mis à jour ou inséré des tuples dans une table.
Automatiquement placé par une clause CREATE INDEX. |
Conflits avec les modes ROW EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE et ACCESS EXCLUSIVE. Ce mode protège une table contre les mises à jour concurrentes.
Conflits avec les modes ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE and ACCESS EXCLUSIVE. Ce mode est plus restrictif que le mode SHARE car une seule transaction à un moment donné peut manipuler ce verrou.
Conflits avec les modes ROW SHARE, ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE et ACCESS EXCLUSIVE. Ce mode est cependant plus restrictif que SHARE ROW EXCLUSIVE; il bloque toutes les requêtes concurrentes SELECT FOR UPDATE.
Automatiquement placé par les clauses ALTER TABLE, DROP TABLE, VACUUM. |
C'est le mode de verrouillage le plus restrictif, il est en conflit avec tous les autres modes et protège une table verrouillée de toutes les opérations concurrentes.
Ce mode est aussi placé par un LOCK TABLE non qualifié (i.e. la commande sans une option mode de verrouillage explicite). |
Le verrou est appliqué
Message retourné si table n'existe pas.
Postgres utilise le plus souvent possible le mode de verrouillage le moins restrictif. LOCK TABLE est fournit pour les cas où vous avez besoin de verrouillage plus restrictif.
Par exemple, une application lance une transaction au niveau isolation READ COMMITTED et a besoin d'assurer l'existence de données dans une table pour la durée de la transaction. Pour terminer là dessus vous pouvez utiliser le mode de verrouillage SHARE sur la table avant de lancer la requête. Ceci protégera les données des changements concurrents et permet d'avantage d'opérations de lecture sur la table avec les données dans leur état actuel, parce que le mode SHARE est en conflit avec n'importe quel ROW EXCLUSIVE plcé par les écritures, et votre clause LOCK TABLE table IN SHARE MODE attendra jusqu'a ce que les opérations d'écriture concurrentes soient validées ou annulées.
Pour lire des données dans leur état réel courant, quand une transaction au niveau isolation sérialisable est en cours, vous executez une clause LOCK TABLE avant l'exécution d'une clause DML, quand la transaction définit quels changements concurrents seront visible par elle-même. |
En plus des conditions ci-dessus, si une transaction est en train de modifier des données dans une table alors le mode SHARE ROW EXCLISIVE sera placé pour prévenir les conditions de verrou mortel quand deux transactions concurrentes essaient de verrouiller la table en mode SHARE et essaient de modifier des données dans la table, les deux (implicitement) acquérant les modes ROW EXCLUSIVE qui sont en conflit avec le verrou concurrent SHARE.
Pour continuer avec le verrou mortel (quand deux transactions en attendent une autre), vous devrez suivre deux règles générales pour éviter les conditions de verrou mortel :
Les transactions ont des verrous placés sur les mêmes objets et dans le même ordre.
Par exemple, si une application met à jour la ligne R1 et la ligne R2 (dans la même transaction), alors la seconde application ne pourra pas mettre à jour la ligne R2 si elle met à jour la ligne R1 plus tard (dans une transaction unique). Au lieu de cela elle mettra à jour les lignes R1 et R2 dans le même ordre que la première application.
Les transactions auront deux mode de verrouillage conflictuels seulement si un des deux est self-conflicting (i.e. peut être manipulé par une transaction à un moment seulement). Si des modes de verrouillage multiples sont embrouillés, alors les transactions acquéront toujours le mode le plus restrictif en premier.
Un exemple de cette règle a été donné quand nous avons parlé de l'utilisation du mode SHARE ROW EXCLUSIVE plutôt que du mode SHARE.
Postgres détecte les verrous mortels et annulera au moins une transaction en attente pour résoudre le verrou mortel. |
Illustre un verrou LOCK sur une table clé primaire pendant des inserts dans une table clé étrangère :
BEGIN WORK; LOCK TABLE films IN SHARE MODE; SELECT id FROM films WHERE name = 'Star Wars: Episode I - The Phantom Menace'; -- Do ROLLBACK if record was not returned INSERT INTO films_user_comments VALUES (_id_, 'GREAT! I was waiting for it for so long!'); COMMIT WORK; |
Place un verrou SHARE ROW EXCLUSIVE sur une table clé primaire pendant une opération de suppression :
BEGIN WORK; LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE; DELETE FROM films_user_comments WHERE id IN (SELECT id FROM films WHERE rating < 5); DELETE FROM films WHERE rating < 5; COMMIT WORK; |
Il n'y a pas de LOCK TABLE en SQL92, qui à la place utilise SET TRANSACTION pour spécifier les niveaux de concurrence sur les transactions. Postgres supporte ça aussi, voir SET pour les details.