2015-04-15 13:16 GMT-03:00 Rosana de Oliveira <[email protected]>:
> 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
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral