LOCK

Nom

LOCK -- verrouille une table

Synopsis

LOCK [ TABLE ] nom [, ...] [ IN mode_verrou MODE ] [ NOWAIT ]

où mode_verrou fait partie
de :

    ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

Description

LOCK TABLE obtient un verrou de niveau table, attendant si nécessaire que tous les verrous en conflit soient lâchés. 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 gardé jusqu'à la fin de la transaction en cours. (Il n'y a pas de commande UNLOCK TABLE ; les verrous sont toujours abandonné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 fourni pour les cas où vous pourriez avoir besoin de verrous plus restrictifs. Par exemple, supposez qu'une application exécute une transaction au niveau d'isolation de lecture validé (Read Committed) pour s'assurer que les données de la table restent stables pendant la durée de la transaction. Pour réaliser ceci, vous pouvez obtenir un mode de verrou SHARE sur la table avant d'envoyer la requête. Ceci empêche toute modification concurrente des données et assure que les lectures de la table voient une vue stable des données validées parce que le mode de verrou SHARE est en conflit avec le verrou ROW EXCLUSIVE acquis par les modificateurs et votre instruction LOCK TABLE nom IN SHARE MODE attend jusqu'à ce que tous déteneurs concurrents de verrous en mode ROW EXCLUSIVE valident ou annulent. Du coup, une fois le verrou obtenu, il ne reste aucune écriture en attente ; de plus, aucune ne peut commencer tant que vous n'avez pas supprimé le verrou.

Pour obtenir un effet similaire lors de l'exécution d'une transaction au niveau d'isolation sérialisable, vous devez exécuter l'instruction LOCK TABLE avant d'exécuter toute instruction SELECT ou toute instruction de modification de données. La vue des données par une transaction sérialisable des données est gelée à la première instruction SELECT ou à la première instruction de modification des données. Un LOCK TABLE plus tard empêche toujours les écritures concurrentes — mais il n'assure pas que ce que la transaction lit correspond aux dernières données validées.

Si une transaction de cette sorte va modifier les données de la table, alors elle doit utiliser le mode de verrou SHARE ROW EXCLUSIVE au lieu du mode SHARE. Ceci nous assure que seule une transaction de ce type est en exécution à la fois. Sans cela, un verrou mortel est possible : deux transactions pourraient acquérir à la fois le mode SHARE et être ensuite incapable d'acquérir aussi le mode ROW EXCLUSIVE pour réellement effectuer leur mises à jour. (Notez que les propres verrous d'une transaction ne sont jamais en conflit, donc une transaction peut acquérir le mode ROW EXCLUSIVE lorsqu'il tient le mode SHARE — mais pas si quelqu'un d'autre détient le mode SHARE.) Pour éviter les verrous bloquants, assurez-vous que toutes les transactions acquièrent des verrous sur les mêmes objets dans le même ordre, et si des modes multiples de verrous sont impliqués pour un seul objet, alors les transactions doivent toujours acquérir en premier le mode le plus restrictif.

Plus d'informations sur les modes de verrou et les stratégies de verrouillage sont disponibles dans Section 12.3.

Paramètres

nom

Le nom d'une table existante à verrouiller (pouvant être 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 spécifié dans la commande LOCK TABLE.

modeverrou

Le mode verrou spécifie avec quels verrous ce verrou entre en conflit. Les modes de verrous sont décrits dans Section 12.3.

Si aucun mode de verrou n'est spécifié, alors ACCESS EXCLUSIVE, le mode le plus restrictif, est utilisé.

NOWAIT

Spécifie que LOCK TABLE n'attend pas que les verrous conflictuels soient annulés : si le verrou spécifié ne peut être acquis immédiatement, sans attendre, la transaction est annulée.

Notes

LOCK TABLE ... IN ACCESS SHARE MODE requiert les droits SELECT sur la table cible. Tous les autres formats de LOCK requièrent les droits UPDATE et/ou DELETE.

LOCK TABLE est utile seulement dans un bloc de transaction (paire BEGIN/COMMIT), car le verrou est supprimé aussitôt que la transaction se termine. Une commande LOCK apparaissant à l'extérieur de tout bloc de transaction forme une transaction contenue dans elle-même, donc le verrou est supprimé dès qu'il est obtenu.

LOCK TABLE s'occupe seulement des verrous au niveau table et du coup, les noms de mode impliquant ROW sont 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. De plus, le mode ROW EXCLUSIVE est un verrou de table partageable. Gardez en tête que tous les modes de verrou ont des sémantiques identiques en ce qui concerne LOCK TABLE, différant seulement dans les règles de conflit entre les modes. Pour des informations sur la façon d'acquérir un réel verrou au niveau ligne, voir Section 12.3.2 et Clause FOR UPDATE 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 - The Phantom Menace';
-- 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, qui utilise à la place SET TRANSACTION pour spécifier des niveaux de concurrence sur les transactions. PostgreSQL a aussi cela ; voir SET TRANSACTION pour les détails.

Sauf pour les 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.