Em algumas respostas , fui informado de que NOWAIT
é necessário evitar impasses, o que me surpreendeu porque não é mencionado na documentação do Postgres sobre bloqueios e impasses
Dadas as 3 sessões seguintes:
CREATE TABLE my_table (id int primary key);
-- Session 1
BEGIN;
SELECT id FROM my_table
WHERE id IN (1,2,5)
ORDER BY id
FOR UPDATE
-- Session 2, started after the select in session 1 (before it is committed)
BEGIN
SELECT id FROM my_table
WHERE id IN (4,5,6)
ORDER BY id
FOR UPDATE
-- Session 3, started after the select in session 2 (before 1 or 2 are committed)
BEGIN
SELECT id FROM my_table
WHERE id IN (5,6,7)
ORDER BY id
FOR UPDATE
Eu pensei que cada consulta esperaria uma vez que chegasse a uma linha bloqueada e continuaria bloqueando na ordem especificada por ORDER BY
. No entanto, com base nessas respostas, parece que a ordem de bloqueio não é garantida mesmo com um ORDER BY
e é possível que essas instruções possam travar?
Espero evitar o uso NOWAIT
porque o cenário em que estou trabalhando faz parte de uma transação bastante grande e, presumivelmente, o erro resultante invalidaria a transação e eu teria que revertê-la e começar tudo de novo.
As transações são relativamente rápidas, então não me importo de esperar se puder evitar impasses.
Se for verdade que o acima não garante o pedido, a única maneira que vejo de fazer isso seria
SELECT id FROM my_table WHERE id = 1 FOR UPDATE;
SELECT id FROM my_table WHERE id = 2 FOR UPDATE;
...etc
O que parece tedioso. Existe uma maneira melhor?