- Ouvrir deux connexions en parallèle, comme deux instances de
psql
ou deux fenêtres de requête dans pgAdmin (chacune a sa propre session). - Démarrez une transaction dans chaque connexion.
BEGIN;
- Exécutez tour à tour des commandes en conflit.
- Avant de pouvoir valider, l'un des deux sera annulé avec une exception de blocage.
- Vous voudrez peut-être annuler l'autre.
ROLLBACK;
Explicitement verrouiller les tables est aussi simple que :
LOCK tbl;
Le verrouillage des lignes peut être fait avec :
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
Ou FOR SHARE
etc. Détails dans le manuel.
(Ou implicitement avec UPDATE
ou DELETE
.)
Exemple
Votre exemple ajouté ne peut pas bloquer. Les deux essaient d'abord de prendre le même verrou sur la même ligne de la même table. Le second attendra que le premier se termine.
Exemple pour produire réellement un interblocage (les lignes doivent exister ou aucun verrou ne sera pris) :
Transaction 1 Transaction 2
BEGIN;
BEGIN;
SELECT salary1
FROM deadlock_demonstration
WHERE worker_id = 1
FOR UPDATE;
SELECT salary1
FROM deadlock_demonstration
WHERE worker_id = 2
FOR UPDATE;
UPDATE deadlock_demonstration
SET salary1 = 100
WHERE worker_id = 2;
UPDATE deadlock_demonstration
SET salary1 = 100
WHERE worker_id = 1;
--> ... 💣 deadlock!
Résultat
L'OP user3388473 a fourni cette capture d'écran après avoir vérifié la solution :