On 15-04-2015 13:16, Rosana de Oliveira wrote:
> 1. Qual a explicação literária e do Postgresql para esta tentativa mal
> sucedida de obter o lock?
>
Vamos entender o que ocorreu na transação A.
begin;
insert into animal values (108, 'viralata', 1);
euler=# select relation::regclass,locktype,virtualtransaction as
vtxn,pid,mode from pg_locks order by pid,relation;
relation | locktype | vtxn | pid | mode
-------------+---------------+------+------+------------------
pessoa | relation | 2/21 | 2794 | RowShareLock
pessoa_pkey | relation | 2/21 | 2794 | AccessShareLock
animal | relation | 2/21 | 2794 | RowExclusiveLock
| virtualxid | 2/21 | 2794 | ExclusiveLock
| transactionid | 2/21 | 2794 | ExclusiveLock
A inserção foi na tabela animal mas como há uma chave estrangeira para
tabela pessoa, o SGBD tem que garantir que ninguém irá modificar o
registro envolvido (por isso ele coloca um RowShareLock na tabela pessoa).
> 1.1 Quem 'lockou' o quê?
>
Na segunda transação:
euler=# begin;
BEGIN
euler=# select nome from pessoa for update;
euler=# select relation::regclass,locktype,virtualtransaction as
vtxn,pid,mode from pg_locks order by pid,relation;
relation | locktype | vtxn | pid | mode
-------------+---------------+------+------+---------------------
pessoa | relation | 3/41 | 2728 | RowShareLock
pessoa | tuple | 3/41 | 2728 | AccessExclusiveLock
pessoa_pkey | relation | 3/41 | 2728 | AccessShareLock
| transactionid | 3/41 | 2728 | ShareLock
| virtualxid | 3/41 | 2728 | ExclusiveLock
pessoa | relation | 2/21 | 2794 | RowShareLock
pessoa_pkey | relation | 2/21 | 2794 | AccessShareLock
animal | relation | 2/21 | 2794 | RowExclusiveLock
| transactionid | 2/21 | 2794 | ExclusiveLock
| virtualxid | 2/21 | 2794 | ExclusiveLock
[não usei o NOWAIT para deixar a transação B esperando para que eu possa
obter a saída dos locks]
O SELECT ... FOR UPDATE tenta obter um AccessExclusiveLock (segunda
linha) em todas as tuplas da tabela mas isso não é possível porque uma
das tuplas (codp = 1) está com um lock "FOR KEY SHARE" (vide tabela 13-3
em [1]) para impossibilitar alguém de alterar o codp da tupla 1 ou mesmo
remover a tupla 1 (essa garantia é necessária para manter a integridade
dos dados).
> 2. Só de curiosidade, fizemos o mesmo teste no Oracle e não ocorreu erro
> algum.
> E agora?
> Quem poderá nos defender?? rss
>
Muito estranho ele não falhar (no caso do NOWAIT) ou ficar esperando
(sem NOWAIT) pois isso pode acarretar perda de integridade. O que
acontece se na transação B você alterar o codp de 1 para 2?
Vale ressaltar que em versões anteriores a 9.3, UPDATE em tuplas de uma
chave estrangeira (como é o caso dos seus UPDATEs na transação B) ficam
bloqueados. A partir da 9.3, eles podem ser feitos desde que você *não*
altere a chave primária da tabela pessoa.
[1] http://www.postgresql.org/docs/9.4/static/explicit-locking.html
--
Euler Taveira Timbira - http://www.timbira.com.br/
PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral