OI, Charly,
Fiz os testes aqui, e é como vc passou. Realmente ajuda!
Valeu, Muito Obrigado!


2009/8/12 Charly Frankl <[email protected]>

> Bom dia Leandro...
>
> Concordo com você que seja um tanto quanto "decepcionante" você não
> conseguir um lock para consultas, mas como tratado, faz parte do modelo
> relacional. Também tive essa dificuldade no início, quando vim trabalhar com
> bancos relacionais.
>
> Bem, mas como comentei, uma forma de "burlar" esta restrição é utilizar a
> instrução "FOR UPDATE NOWAIT". Segue um exemplo:
>
> Em uma seção do psql (pgadmin, aplicação da empresa, etc...) aberta eu
> realizo um select:
>
> begin;
> select *  from municipio where cod_uf = 43 FOR UPDATE NOWAIT;
>
> (Observe que eu não fechei a transação...)
>
> Se em outra seção aberta eu realizar o mesmo select :
> begin;
> select *  from municipio where cod_uf = 43 FOR UPDATE NOWAIT;
>
> O banco simplesmente me retorna a mensagem:
> ERROR:  could not obtain lock on row in relation "municipio"
>
> Bem... É uma forma de burlar o problema a princípio, mas como já discutido
> aqui, o melhor a fazer (ao menos a médio prazo) é rever a aplicação. Depois
> de revista, ai sim você pode optar pelo melhor modelo. Utilizar o FOR UPDATE
> NOWAIT em consultas de atualização não é um erro, mas utilizá-lo
> indiscriminadamente pode trazer transtornos e "efeitos colaterais" não
> desejados. Todavia, como cada caso exige uma solução específica, fica ai a
> sugestão.
>
>
> Espero ter ajudado.
>
> Att,
>
>
>
> --
> Charly Frankl
> http://javadevilopers.blogspot.com/
> [email protected]
> Linux user #391083
>
>
>
>
>
> 2009/8/12 JotaComm <[email protected]>
>
>> Olá, Miguel
>>
>> Faça o seguinte:
>>
>> Sessão A:
>> BEGIN;
>> UPDATE tabela SET codigo=100 WHERE codigo=1;
>> --Vá para a sessão B
>>
>>
>> Sessão B:
>> BEGIN; --Opcional
>> SELECT * FROM tabela WHERE codigo=1;
>> --Aqui você ainda verá o registro 1, porque a transação (Sessão A) que
>> está alterando o registro não fez o commit, então consequentemente você não
>> consegue através desta sessão ver que o registro foi modificado. Para ver
>> que o registro 1 não existe mais é necessário executar o comando COMMIT na
>> Sessão A.
>>
>> Qualquer dúvida pergunta ai.
>>
>> 2009/8/12 MIGUEL JOSE DE LIMA <[email protected]>
>>
>> Bom dia,
>>> Leandro, eu concordo com vc, talvez tenho que aprender a conviver com os
>>> conceitos
>>> de Banco de Dados Relacional e SQL..., mas confesso a vc que para mim é
>>> meio
>>> decepicionante, não conseguir LOCAR um registro para leitura e poder
>>> tratar isso.
>>> Até velho bom antigo CLIPPER fazia isso, vc imagina eu acostumado a fazer
>>> isso
>>> por logos anos, também com ADABAS.
>>> Mas eu gostaria, se possível, de lhe perguntar: COMO É POSSÍVEL ATUALIZAR
>>>
>>> UM SALDO DE QUALQUER COISA (estoque/contacorrente), SEM PRENDER O
>>> REGISTRO PARA LEITURA? COMO POSSO SIMULAR ISSO?
>>> Obs.: Como algumas pessoas já tentaram me ajudar..., informa mais uma vez
>>> que
>>>          o SELECT ... FOR UPDATE não bloquei leitura!
>>>
>>> Obrigado!
>>>
>>>  2009/8/11 Leandro Henrique Pereira Neto <
>>> [email protected]>
>>>
>>>>  Pelo que conheço não é uma questão do PostgreSQL e sim de bancos padrão
>>>> SQL, pelo menos nos mais populares (SqlServer, Oracle, MySQL, PostgreSQL e
>>>> DB2).
>>>>
>>>>
>>>> O SELECT "simples" nunca é bloqueado (somente se usar for update).
>>>> Porém usar todos os SQL com FOR UPDATE pode travar todo o seu sistema
>>>> rapidinho já que somente uma transação poderá ler os dados de cada vez, 
>>>> como
>>>> em sistema OLTP temos normalmente mais leitura do que alteração a coisa
>>>> acaba ficando complicada.
>>>>
>>>> O que tem são os conceitos de transação e de consistência de leitura.
>>>>
>>>> Talvez seja o caso de você pensar o sistema em temos de bancos SQL e não
>>>> tentar fazer no PostgreSQL o que um banco como o Adabas faz pois estruturas
>>>> de funcionamento e implementação totalmente diferentes.
>>>>
>>>> Leandro Henrique Pereira Neto
>>>> Administração de bancos de dados
>>>>
>>>>
>>>>
>>>>
>>>> Charly Frankl escreveu:
>>>>
>>>> Miguel, boa noite...
>>>>
>>>> Para você bloquear os selects, faça todos com FOR UPDATE ... Ai você tem
>>>> opções, onde para retornar logo que está "ocupado" utilize NOWAIT.
>>>>
>>>> Att,
>>>>
>>>>
>>>> 2009/8/11 JotaComm <[email protected]>
>>>>
>>>>> Olá, Miguel
>>>>>
>>>>> Já comentei no email anterior e fiz uma pequena descrição de como isso
>>>>> funciona. Você deu uma olhada no exemplo que mandei?
>>>>>
>>>>> O PostgreSQL não bloqueia a leitura (SELECT), apenas operações de
>>>>> escrita (UPDATE e DELETE).
>>>>>
>>>>>
>>>>>  2009/8/11 MIGUEL JOSE DE LIMA <[email protected]>
>>>>>
>>>>>> Oi Mário, Este é o problema a leitura nunca é bloqueada.
>>>>>>  Fiz os testes pedidos, mas para mim não mudou nada!
>>>>>> Veja:
>>>>>> - Na sessão 1:
>>>>>>   db_teste=# BEGIN WORK;
>>>>>>  BEGIN
>>>>>>  db_teste=# LOCK TABLE tab_material IN ROW EXCLUSIVE MODE NOWAIT;
>>>>>>  LOCK TABLE
>>>>>>   db_teste=# UPDATE tab_material SET desc_serma = 'LAPIS Y' where
>>>>>> codg_serma='10';
>>>>>>  UPDATE 1
>>>>>>  db_teste=#   *** aguardando novo comando ***
>>>>>>  - Na sessão 2:
>>>>>>    db_teste=# BEGIN WORK;
>>>>>>   BEGIN
>>>>>>    db_teste=# SELECT * FROM tab_material where codg_serma='10';
>>>>>>   codg_empr | codg_serma |  id_serma  | desc_serma
>>>>>>
>>>>>>    
>>>>>> -----------+------------+------------+------------+--------------+------
>>>>>>    202       |         10 | 2020000010 | LAPIS Y    |
>>>>>>
>>>>>> É isso ai!!!??
>>>>>> Obrigado.
>>>>>>
>>>>>>  2009/8/11 Mário Oshiro <[email protected]>
>>>>>>
>>>>>>> Em SQLServer, fiz um teste parecido com o seu.
>>>>>>>
>>>>>>> Qdo vc faz um lock de registro ou trabela,  ele nao bloqueia a
>>>>>>> leitura
>>>>>>> de outras sessoes, ate' que a
>>>>>>> sessao de posse do lock, faça um update de algum dado do registro.
>>>>>>>
>>>>>>> Para bloquear o select que vc fez, faca em seguida um update com a
>>>>>>> mesmo
>>>>>>> where assim :
>>>>>>>
>>>>>>>  db_teste=# SELECT * FROM tab_material where codg_serma='10' FOR
>>>>>>> UPDATE;
>>>>>>>   update tab_material set codg_serma='10' where codg_serma='10' ;
>>>>>>>
>>>>>>> teste la e depois envie o resultado.
>>>>>>>
>>>>>>> até mais.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> MIGUEL JOSE DE LIMA wrote:
>>>>>>> > Caros, participantes...
>>>>>>> > Sou iniciante neste mundo do PostgreSQL.
>>>>>>> > Trabalho com outro Banco de Dados - ADABAS (UNIX
>>>>>>> SOLARIS/MAINFRAME),
>>>>>>> > mas me incubiram de fazer testes no PostgreSQL para bloquer
>>>>>>> registros.
>>>>>>> > Então...
>>>>>>> >
>>>>>>> > Estou precisando de ajuda para bloquear a leitura de um registro,
>>>>>>> ou
>>>>>>> > seja,
>>>>>>> > em um cenário como:
>>>>>>> >  "Atualização de Estoque de um Material" :
>>>>>>> > Antes de atualizar o estoque do material selecionado eu preciso
>>>>>>> > bloquear o registro para que
>>>>>>> > nenhuma outra sessão possa obter o dado do registro.
>>>>>>> > PRECISO DE UMA LEITURA EXCLUSIVA - TOTALMENTE RESTRITIVA.
>>>>>>> > Estou usando o PostgreSQL 8.3.7 para os testes - em linux
>>>>>>> > Já li e reli sobre o Isolamento de Transação, mas pode ser que eu
>>>>>>> não
>>>>>>> > esteja entendendo...???
>>>>>>> > Fiz o seguinte teste via psql:
>>>>>>> > - Na Sessão "A"
>>>>>>> >   db_teste=# BEGIN WORK;
>>>>>>> >   BEGIN
>>>>>>> >   db_teste=# LOCK TABLE tab_material IN ROW EXCLUSIVE MODE NOWAIT;
>>>>>>> >   LOCK TABLE
>>>>>>> >   db_teste=# SELECT * FROM tab_material where codg_serma='10' FOR
>>>>>>> UPDATE;
>>>>>>> >   resultado obtido ok!
>>>>>>> >   *** aqui eu preciso bloquear todos os materiais/itens (de um
>>>>>>> pedido)
>>>>>>> > - como ex. fiz de apenas 1 (um).
>>>>>>> >
>>>>>>> > - Na Sessão "B":
>>>>>>> >     ** Fiz o mesmo SELECT sem a clausula FOR UPDATE:
>>>>>>> >   SELECT * FROM tab_material where codg_serma='10'
>>>>>>> >
>>>>>>> >   ** aqui eu obtive o resultado ok da leitura.
>>>>>>> >      Portanto, é aqui, neste ponto que não deveria permitir nenhuma
>>>>>>> > leitura, já que sessão "A" ainda não terminou!
>>>>>>> >      E AI ALGUÉM PODE ME AJUDAR!?
>>>>>>> >
>>>>>>> > Obrigado!
>>>>>>> >
>>>>>>> >
>>>>>>>
>>>>>>
>
> _______________________________________________
> pgbr-geral mailing list
> [email protected]
> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
>
>
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a