Em 15 de abril de 2015 13:27, Marcos Thomaz <[email protected]>
escreveu:

>
> Em 15 de abril de 2015 11:16, Rosana de Oliveira <[email protected]>
> escreveu:
>
>>
>> Boa tarde a todos.
>>
>> Gostaria de que me auxiliassem a resolver uma dúvida sobre o que está
>> ocorrendo na situação de controle de concorrência abaixo.
>>
>> Não me lembro de ter visto esse caso nas literaturas de Banco de Dados.
>>
>> Fizemos testes nas versões 9.3.5 e 9.4 do Postgresql.
>>
>> O cenário consistem de duas transações sendo executadas concorrentemente
>> no Postgresql.
>> A transação TA faz inserção em uma tabela animal.
>> A transação TB faz update na tabela pessoa, em um campo que não tem nada
>> a ver com a chave estrangeira à tabela animal.
>> O que acontece é que o update da  transação TB é executado normalmente.
>> Porém, se executarmos um SELECT FOR UPDATE, o Postgresql não aceita e dá
>> mensagem de erro, não conseguindo obter o lock.
>>
>>
>>
>> PERGUNTA-SE:
>>
>> 1. Qual a explicação literária e do Postgresql para esta tentativa mal
>> sucedida de obter o lock?
>>
>> 1.1 Quem 'lockou' o quê?
>>
>> 2. Só de curiosidade, fizemos o mesmo teste no Oracle e não ocorreu erro
>> algum.
>>    E agora?
>>    Quem poderá nos defender??   rss
>>
>>
>>
>> Segue abaixo o script ...
>>
>>
>>
>>
>>
>> --1.a tabela
>> create table pessoa(
>> codp integer primary key,
>> nome varchar(10)
>> );
>>
>> --2.a tabela
>> create table animal(
>> coda integer primary key,
>> raca varchar(10),
>> codp integer references pessoa(codp)
>> );
>>
>>
>> -- inserção de dados
>> insert into pessoa values (1, 'rosa');
>> insert into pessoa values (2, 'maria');
>> insert into pessoa values (3, 'josé');
>>
>>
>>
>>  -- transacao - TA
>>
>> begin;
>> insert into animal values (108, 'viralata', 1);
>>
>> select * from animal;
>> select * from pessoa;
>>
>>
>>
>> --transacao  -TB
>>
>> begin;
>> update pessoa set nome = 'rosana' where nome = 'rosa';     -- executado
>> com sucesso
>>
>> update pessoa set nome = 'rosa de' where codp=1;  -- executado com
>> sucesso
>>
>> select nome from pessoa  for update nowait;   -- erro!
>>
>>
>> ********** Error **********
>>
>> ERROR: could not obtain lock on row in relation "pessoa"
>> SQL state: 55P03
>>
>>
>> Atenciosamente,
>>
>> --
>> Rosana de Oliveira Santos
>>
>> _______________________________________________
>> pgbr-geral mailing list
>> [email protected]
>> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
>>
>>
> Correndo o risco de estar falando besteira, e sem nenhuma comprovação
> literária, mas quando você dá um update dentro da transação, o registro não
> ficaria bloqueado?
> Digo isso porque se a ideia é bloquear até o final da alteração, o ideal
> seria o uso do select for update antes dos comandos de alteração,
> garantindo o bloqueio, que seria liberado após a conclusão da transação
> (commit/rollback). Se o update por si só já bloquear o registro, o select
> for update iria falhar (pois está sendo colocado depois), não seria isso?
>
> --
>
>
> Marcos Thomaz da Silva
> Analista de Tecnologia da Informação
>
> _______________________________________________
> pgbr-geral mailing list
> [email protected]
> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
>
>


O nível de isolamento do Postgresql é o "read committed".
Não sei qual é o do Oracle. Esqueçam-no.  Uma resposta da literatura formal
(Date, Navathe, Silberchatz) para mim, seria suficiente.

Só para explicar, o cenário que coloquei foi totalmente didático.
As operações de update, seguido de SELECT for UPDATE não necessariamente
precisam estar em sequência. Não é isto que estou questionando.
E sim, porque o update funciona e o SELECT FOR UPDATE NÃO?


Grata,

-- 
Rosana de Oliveira Santos
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a