LOCK
LOCK — verrouiller une table
Synopsis
LOCK [ TABLE ] nom [, ...] [ IN mode_verrou MODE ] [ NOWAIT ]
où mode_verrou peut être :
ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
Description
LOCK TABLE
prend un
verrou de niveau table, attendant si nécessaire que tout verrou
conflictuel soit relâché. Si NOWAIT est
spécifié,
LOCK TABLE
n'attend pas l'acquisition du verrou désiré : s'il ne peut pas être
obtenu immédiatement, la commande est annulée et une erreur est
émise. Une fois obtenu, le verrou est conservé jusqu'à la fin de la
transaction en cours. (Il n'y a pas de commande
UNLOCK TABLE
; les verrous sont
systématiquement relâchés à la fin de la transaction.)
Lors de l'acquisition automatique de verrous pour les commandes qui
référencent des tables, PostgreSQL™ utilise toujours le mode de
verrou le moins restrictif possible.
LOCK TABLE
est utilisable
lorsqu'il est nécessaire d'obtenir des verrous plus restrictifs.
Soit, par exemple, une application qui exécute une transaction de
niveau d'isolation « lecture des validés » (
Read
Committed
). Pour s'assurer que les données de la table
sont immuables pendant toute la durée de la transaction, un verrou
SHARE de niveau table peut être obtenu
avant d'effectuer la requête. Cela empêche toute modification
concurrente des données. Cela assure également que toute lecture
intervenant ensuite sur la table accède à la même vue des données
validées. En effet, un verrou SHARE entre
en conflit avec le verrou ROW EXCLUSIVE
pris par les modificateurs et l'instruction
LOCK TABLE
nom
IN SHARE MODE
attend que tout détenteur concurrent de verrous de mode ROW EXCLUSIVE valide ou annule. De ce fait, une fois
le verrou obtenu, il ne reste aucune écriture non validée en
attente ; de plus, aucune ne peut commencer tant que le verrou
acquis n'est pas relâché.
Pour obtenir un effet similaire lors de l'exécution d'une
transaction de niveau d'isolation sérialisable, il est nécessaire
d'exécuter l'instruction
LOCK
TABLE
avant toute instruction
SELECT
ou de modification de
données. La vue des données utilisée par une transaction
sérialisable est figée au moment où débute la première instruction
SELECT
ou de
modification des données. Un
LOCK
TABLE
ultérieur empêche encore les écritures
concurrentes -- mais il n'assure pas que la transaction lit les
dernières données validées.
Si une telle transaction modifie les données de la table, elle doit
utiliser le mode de verrou SHARE ROW
EXCLUSIVE au lieu du mode SHARE. Cela
assure l'exécution d'une seule transaction de ce type à la fois.
Sans cela, une situation de verrou mort est possible : deux
transactions peuvent acquérir le mode SHARE et être ensuite incapables d'acquérir aussi le
mode ROW EXCLUSIVE pour réellement
effectuer leurs mises à jour. (Les verrous d'une transaction ne
sont jamais en conflit. Une transaction peut de ce fait acquérir le
mode ROW EXCLUSIVE alors qu'elle détient
le mode SHARE -- mais pas si une autre
transaction détient le mode SHARE.) Pour
éviter les verrous bloquants, il est préférable que toutes les
transactions qui acquièrent des verrous sur les mêmes objets le
fassent dans le même ordre. De plus si de multiples modes de
verrous sont impliqués pour un même objet, le verrou de mode le
plus restrictif doit être acquis le premier.
Plus d'informations sur les modes de verrou et les stratégies de
verrouillage sont disponibles dans Section 12.3,
« Verrouillage explicite ».
Paramètres
-
nom
-
Le nom d'une table à verrouiller (éventuellement qualifié du
nom du schéma).
La commande LOCK a, b; est
équivalente à LOCK a; LOCK b;. Les
tables sont verrouillées une par une dans l'ordre précisé par
la commande
LOCK
TABLE
.
-
modeverrou
-
Le mode de verrou précise les verrous avec lesquels ce verrou
entre en conflit. Les modes de verrou sont décrits dans
Section 12.3,
« Verrouillage explicite ».
Si aucun mode de verrou n'est précisé, ACCESS EXCLUSIVE, mode le plus restrictif, est
utilisé.
-
NOWAIT
-
LOCK TABLE
n'attend pas que les verrous conflictuels soient relâchés :
si le verrou indiqué ne peut être acquis immédiatement sans
attente, la transaction est annulée.
Notes
LOCK TABLE ... IN ACCESS SHARE MODE
requiert les droits SELECT sur la table
cible. Toutes les autres formes de
LOCK
requièrent les droits
UPDATE et/ou DELETE.
LOCK TABLE
n'est
utile qu'à l'intérieur d'un bloc transactionnel (paire
BEGIN
/
COMMIT
), puisque le verrou est
supprimé dès que la transaction se termine. Une commande
LOCK
à l'extérieur de
tout bloc transactionnel constitue une transaction auto-contenue.
Le verrou est alors supprimé aussitôt obtenu.
LOCK TABLE
ne
concernent que les verrous de niveau table. Les noms de mode
contenant ROW sont donc tous mal nommés.
Ces noms de modes doivent généralement être compris comme indiquant
l'intention de l'utilisateur d'acquérir des verrous de niveau ligne
à l'intérieur de la table verrouillée. Le mode ROW EXCLUSIVE est également un verrou de table
partageable. Tous les modes de verrou ont des sémantiques
identiques en ce qui concerne
LOCK
TABLE
; ils ne diffèrent que dans les règles de
conflit entre les modes. Pour des informations sur la façon
d'acquérir un vrai verrou de niveau ligne, voir Section 12.3.2,
« Verrous au niveau ligne » et Clause FOR
UPDATE/FOR SHARE
dans la
documentation de référence de
SELECT
.
Exemples
Obtenir un verrou SHARE sur une table avec
clé primaire avant de réaliser des insertions dans une table
disposant de la clé étrangère :
BEGIN WORK;
LOCK TABLE films IN SHARE MODE;
SELECT id FROM films
WHERE nom = 'Star Wars : Episode I - La menace fantôme';
-- Effectuer un ROLLBACK si aucun enregistrement n'est retourné
INSERT INTO commentaires_films VALUES
(_id_, 'SUPER ! Je l''attendais depuis si longtemps !');
COMMIT WORK;
Prendre un verrou SHARE ROW EXCLUSIVE sur
une table avec clé primaire lors du début des opérations de
suppression :
BEGIN WORK;
LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;
DELETE FROM commentaires_films WHERE id IN
(SELECT id FROM films WHERE score < 5);
DELETE FROM films WHERE score < 5;
COMMIT WORK;
Compatibilité
LOCK TABLE
n'existe
pas dans le standard SQL. À la place, il utilise
SET TRANSACTION
pour spécifier
les niveaux de concurrence entre transactions. PostgreSQL™ en dispose également ; voir
SET TRANSACTION pour les détails.
À l'exception des modes de verrous ACCESS
SHARE, ACCESS EXCLUSIVE et SHARE UPDATE EXCLUSIVE, les modes de verrou
PostgreSQL™ et la syntaxe
LOCK TABLE
sont
compatibles avec ceux présents dans Oracle™.