PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come simulare il deadlock in PostgreSQL?

  1. Apri due connessioni in parallelo, come due istanze di psql o due finestre di query in pgAdmin (ognuna ha la propria sessione).
  2. Avvia una transazione in ogni connessione. BEGIN;
  3. Esegui a turno comandi in conflitto tra loro.
  4. Prima che tu possa eseguire il commit, verrà eseguito il rollback di uno dei due con un'eccezione deadlock.
  5. Potresti voler ripristinare l'altro. ROLLBACK;

Esplicitamente tabelle di blocco è semplice come:

LOCK tbl;

Il blocco delle righe può essere eseguito con:

SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;

Oppure FOR SHARE ecc. Dettagli nel manuale.
(O implicitamente con UPDATE o DELETE .)

Esempio

Il tuo esempio aggiunto non può bloccarsi. Entrambi provano a prendere prima lo stesso blocco sulla stessa riga della stessa tabella. Il secondo aspetterà che il primo finisca.

Esempio per produrre effettivamente un deadlock (devono esistere righe o non verrà preso alcun blocco):

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!

Risultato

L'utente OP3388473 ha contribuito a questo screenshot dopo aver verificato la soluzione: