PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como simular deadlock no PostgreSQL?

  1. Abra duas conexões em paralelo, como duas instâncias de psql ou duas janelas de consulta no pgAdmin (cada uma tem sua própria sessão).
  2. Inicie uma transação em cada conexão. BEGIN;
  3. Execute comandos conflitantes entre si em turnos.
  4. Antes que você possa confirmar, um dos dois será revertido com uma exceção de impasse.
  5. Você pode querer reverter o outro. ROLLBACK;

Explicitamente bloqueando tabelas é tão simples quanto:
LOCK tbl;

O bloqueio de linhas pode ser feito com:
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;

Ou FOR SHARE etc. Detalhes no manual.
(Ou implicitamente com UPDATE ou DELETE .)

Exemplo


Seu exemplo adicionado não pode travar. Ambos tentam primeiro obter o mesmo bloqueio na mesma linha da mesma tabela. O segundo vai esperar o primeiro terminar.

Exemplo para realmente produzir um deadlock (as linhas devem existir ou nenhum bloqueio será feito):
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!

Resultado


O usuário OP3388473 contribuiu com esta captura de tela depois de verificar a solução: