Sim concordo o código que vc me enviou funciona plenamente , soh q preciso q seja muito rapido a execucao e fazendo em um cursor , a tabela será lida inteira , quero q soh retorne a primeira linha "liberada" , bom deixa eu me explicar melhor. Estou desenvolvendo um modulo de estoque , a rotina q estou com problemas eh a rotina q reserva um item do estoque . Esta rotina será invocada pelo módulo de promocoes que vai reservar n itens do estoque passando o tipo e o estoque em questao . Só que a rotina será chamada por um cluster entao sim será chamada no mesmo milissegundo , ou nao , mas vai haver deadlock e quando houver deadlock eu preciso q a minha rotina selecione o proximo item e de um skip no registro travado . Tipo efetuo o select selecionando o tipo do item e o estoque , retorno o item xpto , dai uma outra rotina do meu modulo recebe o codigo do item e altera o status dele para reservado . Só que nesse mesmo segundo a proc pode e provavelmente foi chamada novamente preciso que retorne somente um entao coloco o rownum = 1 , como a celular eu travei com for update nowait skip locked , ele nao acha o rownum = 1 pq ele ta travado pela primeira chamada e da no_data_found. O que fiz para resolver eh colocar num cursor e dar somente um fetch com for update skip locked , dai ele me tras o proximo registro , porem a performance cai , se eu utilizasse o rownum seria melhor , no caso q vc me enviou eh mais ou menos isso tbm , soh que vai executar o plano todo , e preciso q essa proc execute em questao de msecs , nao soh ela como o processo todo desde a tela q chama o banco ateh o modulo de promoces ateh me chamar e voltar pra tela. Acho que agora fez mais sentido Nao soube me expressar nos emails anteriores Se puder me ajudar agradeço muito Valew Chiappa! Acacio
To: [EMAIL PROTECTED]: [EMAIL PROTECTED]: Thu, 22 May 2008 17:58:16 +0000Subject: [oracle_br] Re: Duvida sobre Deadlock No e-mail original vc tinha dito :"..tenho uma tabela preciso fazer um select de um registro travandoesse registro e alterando ele" ... "Porem quando outra sessao efetuaro mesmo select , o registro travado nao pode vir e sim o proximodestravado ."é o que eu fiz, ok ? INCLUSIVE, diferentes execuções duma proc ***NECESSARIAMENTE *** vão sim estar em sessões difentes, então a técnicade pular os regs lockados que eu empreguei funcionaria, sim...E outra,o que acontece na procedure é que normalmente vc tem uma ARGUMENTOindicando qual o registro que vc quer selecionar e updatear, entãoessa lógica de "buscar o próximo" sorry mas penso que ainda não fazmuito sentido... E outra, tal como eu disse, normalmente se vc querter várias sessões fazendo um processamento, Parallel SQL é aindicação....Também não faz sentido "procedure chamada 2x no mesmo milisegundo" -que tipo de sistema vc está construindo que exige isso ??? NormalmenteOU um sistema é OLTP (aonde o usuário consulta um ou mais registros,os analisa na tela e pode ou não desejar alterá-los) ou é BATCH (aondehá a figura da carga de dados, que tipicamente TEM que ser completadaantes de qquer consulta, então a´entra a figura do parallel sql)....Explique direito o que vc quer fazer, que tipo de sistema vc estáconstruindo, o seu ambiente (se modo c/s ou web), pra gente poderentender melhor a sua necessidade...[]sChiappa --- Em [email protected], Manuel Acacio Ludgero Domingos<[EMAIL PROTECTED]> escreveu>> > Entao não eh bem isso ,> > A situacao eh a seguinte tenho uma proc que ira selecionar umregistro e depois fazer update nele , porem essa proc vai ser chamadaem em paralelo podendo ser chamado no mesmo milesimo de segundo ,preciso impedir q em uma chamada x o mesmo registro seja chamado nax+1 , e nao posso deixar a chamada esperando com wait, o exemploabaixo daria certo , se eu pudesse efetuar a leitura da tabela inteiraporem eu nao posso pq a proc deve rodar em questão de milessegundo epreciso prever a volumetria da tabela , uma ideia seria colocar orownum = 1 , mas mesmo no exemplo abaixo se no select do for eucolocasse rownum = 1 , retornaria somente a primeira vez , e a segundae a terceira daria no_data_found , pq o oracle monta o rownum antes dedar lock e o mesmo se eu colocasse for update skip locked .> > Dei um jeito colocando o select em um cursor e dando somente umfetch , porem nao tem rownum no select sendo assim executa o planotodo , perdendo performance .> > Acho q ficou mais claro , veja bem não é ilógico me expressei mal nooutro email :)> > Se puder me ajudar eu agradeço muito.> > Acacio> > > To: [EMAIL PROTECTED]: [EMAIL PROTECTED]: Thu, 22 May 2008 15:38:34+0000Subject: [oracle_br] Re: Duvida sobre Deadlock> > > > > Colega, esse método de trabalho é absolutamente ESTRANHO, nãovejomuito sentido nisso : veja, se eu quero ler a informação eu querolerTODA a informação que existe de acordo com os meus critériosdepesquisa, só depois se eu for alterar aí sim se mais alguémalterouantes eu recebo um msg de erro, acho que nâo receber ainformaçâo queexiste só porque alguém a consultou antes, E receber ainformação numaeventual próxima consulta se o lock já foi removido(mesmo semalteração!) deve ser EXTREMAMENTE CONFUSO pro usuário, não éde modoALGUM um procedimento padrão e recomendado isso .... E lógico,se éuma programa que está fazendo processo em background, pra vctervárias leituras simultâneas (cada sessão fazendo uma leitura deumaparte) é para isso que foi inventado o PARALLEL SQL... Ou pelomenosse poderia fazer Parallel DIY, na mão, via rowid, procureemasktom.oracle.com que vc acha exemplos...Bom, mas sim, dá pra fazer,é algo totalmente sem sentido mas dá prafazer, mas é em PL/SQl e nãoem SQL, exemplo (LOGICAMENTE isso sófunciona entre sessões DIFERENTES,na mesma sessão que fez o lock ela"vê" tudo, lógico):[EMAIL PROTECTED]:SQL>select empno, ename, sal from emp order by sal;EMPNOENAME SAL------------------ ---------- ------------------7369 SMITH8007900 JAMES 9507876 ADAMS 11007521 WARD 12507654 MARTIN 12507934MILLER 13007844 TURNER 15007499 ALLEN 16007782 CLARK 24507698 BLAKE28507566 JONES 29757788 SCOTT 30007902 FORD 30007839 KING 500014linhas selecionadas.==> numa sessão 1 quero ler e travar o primeiroregistro NA ORDEMdesejada (ordem é fundamental aqui, NÃO EXISTE ordem"natural" numatabela) :scott#1:SQL>edGravou file afiedt.buf1 DECLARE2resource_busy exception;3 pragma exception_init( resource_busy, -54);4 v_reg EMP%rowtype;5 BEGIN6 for x in ( select rowid rid from emporder by sal)7 loop8 Begin9 select * into v_reg from emp where rowid =x.rid forupdate nowait;10 dbms_output.put_line('Emp=' || v_reg.empno11|| ',Name=' || v_reg.ename12 || ',Sal=' || v_reg.sal);13 exit;14Exception15 when resource_busy then16 null;17 End;18 end loop;19*END;scott#1:SQL>/Emp=7369,Name=SMITH,Sal=800Procedimento PL/SQLconcluído com sucesso.==> na sessão 2, pulei o registro lockado pelasessão 1 ....scott#2:SQL>DECLARE2 resource_busy exception;3 pragmaexception_init( resource_busy, -54 );4 v_reg EMP%rowtype;5 BEGIN6 forx in ( select rowid rid from emp order by sal)7 loop8 Begin9 select *into v_reg from emp where rowid = x.rid forupdate nowait;10dbms_output.put_line('Emp=' || v_reg.empno11 || ',Name=' ||v_reg.ename12 || ',Sal=' || v_reg.sal);13 exit;14 Exception15 whenresource_busy then16 null;17 End;18 end loop;19 END;20/Emp=7900,Name=JAMES,Sal=950Procedimento PL/SQL concluído comsucesso.==> sessão 3, pulei o lock da sessão 1 e da sessão 2, achandoopróximo não-locakdo e o lockando :scott#3:SQL>DECLARE2 resource_busyexception;3 pragma exception_init( resource_busy, -54 );4 v_regEMP%rowtype;5 BEGIN6 for x in ( select rowid rid from emp order bysal)7 loop8 Begin9 select * into v_reg from emp where rowid = x.ridforupdate nowait;10 dbms_output.put_line('Emp=' || v_reg.empno11 ||',Name=' || v_reg.ename12 || ',Sal=' || v_reg.sal);13 exit;14Exception15 when resource_busy then16 null;17 End;18 end loop;19END;20 /Emp=7876,Name=ADAMS,Sal=1100Procedimento PL/SQL concluído comsucesso.[]sChiappa--- Em [email protected], Manuel AcacioLudgero Domingos<acacio_domingos@> escreveu>> > Pessoal , estou com umproblema e talvez vc´s possam me ajudar.> > Seguinte tenho uma tabelapreciso fazer um select de um registrotravando esse registro ealterando dele , utilizei o select for updateskip locked para travar edesprezar os travados.> > Porem quando outra sessao efetuar o mesmoselect , o registrotravado nao pode vir e sim o proximo destravado .>> estou colocando no select um rownum = 1 para q soh retorne umalinha, com isso no segundo select ele despreza o locked e retorna umnodata found pq o rownum = 1 ta locked..> > Uma solucao seria dar umselect por fora e popular o rownum , ouchamar um dense_rank da vida ,porem nao posso ler a tabela toda pqela eh grande e essa proc tem qrodar em questao de milissegundos> > Alguem tem ideia?> >Atenciosamente> Acacio>__________________________________________________________> RecebaGRÁTIS as mensagens do Messenger no seu celular quando vocêestiveroffline. Conheça o MSN Mobile!>http://mobile.live.com/signup/signup2.aspx?lc=pt-br> > [As partesdesta mensagem que não continham texto foram removidas]> > > > > > > > __________________________________________________________> Cansado de espaço para só 50 fotos? Conheça o Spaces, o site derelacionamentos com até 6,000 fotos!> http://www.amigosdomessenger.com.br> > [As partes desta mensagem que não continham texto foram removidas]> _________________________________________________________________ Instale a Barra de Ferramentas com Desktop Search e ganhe EMOTICONS para o Messenger! É GRÁTIS! http://www.msn.com.br/emoticonpack [As partes desta mensagem que não continham texto foram removidas]
