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 pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral