- 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). - Inicie uma transação em cada conexão.
BEGIN;
- Execute comandos conflitantes entre si em turnos.
- Antes que você possa confirmar, um dos dois será revertido com uma exceção de impasse.
- 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: