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
