PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment simuler un blocage dans PostgreSQL ?

  1. 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).
  2. Démarrez une transaction dans chaque connexion. BEGIN;
  3. Exécutez tour à tour des commandes en conflit.
  4. Avant de pouvoir valider, l'un des deux sera annulé avec une exception de blocage.
  5. 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 :