2015-04-15 13:16 GMT-03:00 Rosana de Oliveira <rosana.pi...@gmail.com>:

> 1. Qual a explicação literária e do Postgresql para esta tentativa mal
> sucedida de obter o lock?
>
>
O erro especificamente foi devido ao parâmetro NOWAIT, se removesse este, a
segunda transação ficaria bloqueada aguardando a primeira.


> 1.1 Quem 'lockou' o quê?
>
>
Ok, vamos simplificar o exemplo para entender melhor:

* Preparação (igual ao seu):

    CREATE TABLE pessoa(codp integer RIMARY KEY, nome varchar(10));
    CREATE TABLE animal(coda integer PRIMARY KEY, raca varchar(10), codp
integer REFERENCES pessoa(codp));
    INSERT INTO pessoa VALUES (1, 'rosa');
    INSERT INTO pessoa VALUES (2, 'maria');
    INSERT INTO pessoa VALUES (3, 'josé');

* Transação TA:

    BEGIN;
        INSERT INTO animal VALUES (108, 'viralata', 1);

* Transação TB:

    BEGIN;
        SELECT * FROM pessoa FOR UPDATE NOWAIT; -- ERRO!

O que aconteceu foi, quando você fez o INSERT de "animal" na TA, o
PostgreSQL bloqueou a tupla que esta se refere na tabela "pessoa", nesse
caso a que possue "codp = 1", isso para garantir que a chave estrangeira
não seja removida durante a operação. Internamente o PostgreSQL usa o
seguinte comando quando você faz o INSERT:

    SELECT 1 FROM ONLY pessoa x WHERE x.codp = 1 FOR KEY SHARE OF x;

E quando você executou o SELECT em TB, você incluiu a linha com "codp=1",
que já estava bloqueado pelo comando acima (executado implicitamente com o
INSERT), causando assim um conflito e, como usou o NOWAIT, retornando um
erro. Se quiser verificar isso, exclua o "codp=1" do SELECT em TB e verá
que o erro não é retornado:

    SELECT * FROM pessoa WHERE codp <> 1 FOR UPDATE NOWAIT;

Se você está usando FOR UPDATE, mas sabe que não vai alterar nenhuma chave
UK/PK da tabela, você pode usar o FOR NO KEY UPDATE, que é mutuamente
exclusivo mas não conflita com FOR KEY SHARE (usando pelas chaves
estrangeiras). Veja os demais níveis em [1].

OBS: FOR KEY SHARE é relativamente novo, 9.3 se não me engano.

[1]
http://www.postgresql.org/docs/current/static/explicit-locking.html#LOCKING-ROWS

Atenciosamente,
-- 
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a