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