Só para mostrar que *** Não É Verdade *** que vc não possa identificar as 
sessões que estão Esperando para obter um lock, veja o Exemplo abaixo (em 11gr2 
EE, mas em princípio Independente de versão) : terei 3 janelas separadas (e 
portanto 3 sessões) que vão rodar a mesma rotina que não trata corretamente os 
locks, ficando em loop eterno E não limitando transações nem sessões, vamos 
botar a porimeira para executar :
 
 
 scott#1:SQL>DECLARE
  2    resource_busy exception;
  3    pragma exception_init (resource_busy,-54);
  4    v_num number;
  5  BEGIN
  6     loop
  7        Begin
  8           select 1 into v_num from dept where deptno=10 FOR UPDATE NOWAIT;
  9      update dept set dname='TESTE' where deptno=10;
 10           exit;
 11        Exception
 12           when resource_busy then
 13              null;
 14        End;
 15     end loop;
 16  END;
 17  /

Procedimento PL/SQL concluÝdo com sucesso.

 ==> ok, essa seria a sessão A no seu cenário, como ela foi casualmente a 
primeira ela obtém o lock... Vamos botar pra rodar a mesma rotina com loop 
eterno em outras múltiplas janelas :
 
 SCOTT#2:SQL>DECLARE
  2    resource_busy exception;
  3    pragma exception_init (resource_busy,-54);
  4    v_num number;
  5  BEGIN
  6     loop
  7        Begin
  8           select 1 into v_num from dept where deptno=10 FOR UPDATE NOWAIT;
  9      update dept set dname='TESTE' where deptno=10;
 10           exit;
 11        Exception
 12           when resource_busy then
 13              null;
 14        End;
 15     end loop;
 16  END;
 17  /

 
 => Imediatamente a sessão 'congela' dado o loop eterno, vamos abrir ainda 
outra :
 
 scott#3:SQL>DECLARE
  2    resource_busy exception;
  3    pragma exception_init (resource_busy,-54);
  4    v_num number;
  5  BEGIN
  6     loop
  7        Begin
  8           select 1 into v_num from dept where deptno=10 FOR UPDATE NOWAIT;
  9      update dept set dname='TESTE' where deptno=10;
 10           exit;
 11        Exception
 12           when resource_busy then
 13              null;
 14        End;
 15     end loop;
 16  END;
 17  /

okdoc, as janelas 2 e 3 estão em "freeze" aqui, vamos consultar o status geral 
consultando as views adequadas em uma sessão privilegiada (no caso consultando 
só o usuário SCOTT só por Brevidade de exemplo, claro que em Prod seriam Outras 
as consições de filtro quye vc colocaria na V$SESSION) :

SYSTEM@o11gr2:SQL>select sid, serial#, username, logon_time, event, 
blocking_instance, blocking_session, wait_class, p1, p2, p3, seconds_in_wait 
from v$session where username='SCOTT';

       SID    SERIAL# USERNAME                       LOGON_TI EVENT             
                                       BLOCKING_INSTA
NCE BLOCKING_SESSION WAIT_CLASS                                                 
           P1         P2         P3 SECONDS_IN_WAIT
---------- ---------- ------------------------------ -------- 
---------------------------------------------------------------- ------
----------- ---------------- 
---------------------------------------------------------------- ---------- 
---------- ---------- ------
---------
        14         12 SCOTT                          18/03/13 SQL*Net message 
from client
                  Idle                                                          
   1111838976          1          0             416
        20         17 SCOTT                          18/03/13 buffer busy waits
                  Concurrency                                                   
            4        135          1               0
       141         12 SCOTT                          18/03/13 buffer busy waits
                  Concurrency                                                   
            4        135          1               0

.... espero um pouco ...
SYSTEM@o11gr2:SQL>/

       SID    SERIAL# USERNAME                       LOGON_TI EVENT             
                                       BLOCKING_INSTA
NCE BLOCKING_SESSION WAIT_CLASS                                                 
           P1         P2         P3 SECONDS_IN_WAIT
---------- ---------- ------------------------------ -------- 
---------------------------------------------------------------- ------
----------- ---------------- 
---------------------------------------------------------------- ---------- 
---------- ---------- ------
---------
        14         12 SCOTT                          18/03/13 SQL*Net message 
from client
                  Idle                                                          
   1111838976          1          0             428
        20         17 SCOTT                          18/03/13 buffer busy waits
                  Concurrency                                                   
            4        135          1               0
       141         12 SCOTT                          18/03/13 buffer busy waits
                  Concurrency                                                   
            4        135          1               0

... espero mais um pouco ...

SYSTEM@o11gr2:SQL>/

       SID    SERIAL# USERNAME                       LOGON_TI EVENT             
                                       BLOCKING_INSTA
NCE BLOCKING_SESSION WAIT_CLASS                                                 
           P1         P2         P3 SECONDS_IN_WAIT
---------- ---------- ------------------------------ -------- 
---------------------------------------------------------------- ------
----------- ---------------- 
---------------------------------------------------------------- ---------- 
---------- ---------- ------
---------
        14         12 SCOTT                          18/03/13 SQL*Net message 
from client
                  Idle                                                          
   1111838976          1          0             433
        20         17 SCOTT                          18/03/13 buffer busy waits
                  Concurrency                                                   
            4        135          1               0
       141         12 SCOTT                          18/03/13 buffer busy waits
                  Concurrency                                                   
            4        135          1               0

SYSTEM@o11gr2:SQL>/


==> tá CLARO que está havendo Concorrência enter as sessões 20 e 141 por alguma 
outra, vamos consultar qual é o objeto que elas estão sendo Impedidas de 
acessar :


SYSTEM@o11gr2:SQL>select
  2     owner,
  3     segment_name,
  4     segment_type
  5  from
  6     dba_extents
  7  where
  8     file_id = &P1
  9  and
 10    &P2 between block_id and block_id + blocks -1;
Informe o valor para p1: 4
antigo   8:    file_id = &P1
novo   8:    file_id = 4
Informe o valor para p2: 135
antigo  10:   &P2 between block_id and block_id + blocks -1
novo  10:   135 between block_id and block_id + blocks -1

OWNER                          SEGMENT_NAME                                     
                         SEGMENT_TYPE
------------------------------ 
---------------------------------------------------------------------------------
 ------------------
SCOTT                          DEPT                                             
                         TABLE

SYSTEM@o11gr2:SQL>
 
 
 => MARAVILHA... Vamos ver se há LOCK nesse objeto, se sim tá basicamente 
PROVADO que é o caso que queríamos demonstrar, espera Eterna por locks causada 
por loop eterno :
 
 SYSTEM@o11gr2:SQL>ed
Gravou file afiedt.buf

  1  SELECT session_id, oracle_username, os_user_name, username U_NAME, owner 
OBJ_OWNER,
  2  object_name, object_type, s.osuser,
  3  DECODE(l.block,
  4    0, 'Not Blocking',
  5    1, 'Blocking',
  6    2, 'Global') STATUS,
  7    DECODE(v.locked_mode,
  8      0, 'None',
  9      1, 'Null',
 10      2, 'Row-S (SS)',
 11      3, 'Row-X (SX)',
 12      4, 'Share',
 13      5, 'S/Row-X (SSX)',
 14      6, 'Exclusive', TO_CHAR(lmode)
 15    ) MODE_HELD
 16  FROM gv$locked_object v, dba_objects d,
 17  gv$lock l, gv$session s
 18  WHERE v.object_id = d.object_id
 19  AND (v.object_id = l.id1)
 20  AND v.session_id = s.sid
 21* ORDER BY username, session_id
SYSTEM@o11gr2:SQL>/

SESSION_ID ORACLE_USERNAME                OS_USER_NAME                   U_NAME 
                     OBJ_OWNER                 OBJECT
_NAME                                                                           
                                OBJECT_TYPE
---------- ------------------------------ ------------------------------ 
------------------------------ -----------------------------
- 
--------------------------------------------------------------------------------------------------------------------------------
 --
-----------------
OSUSER                         STATUS       MODE_HELD
------------------------------ ------------ 
----------------------------------------
        14 SCOTT                          Win7_Casa\jlchiappa            SCOTT  
                        SCOTT
  DEPT                                                                          
                                        TABLE
Win7_Casa\jlchiappa            Not Blocking Row-X (SX)

        14 SCOTT                          Win7_Casa\jlchiappa            SCOTT  
                        SCOTT
  DEPT                                                                          
                                        TABLE
Win7_Casa\jlchiappa            Not Blocking Row-X (SX)

       141 SCOTT                          Win7_Casa\jlchiappa            SCOTT  
                     SCOTT
  DEPT                                                                          
                                        TABLE
Win7_Casa\jlchiappa            Not Blocking None

       141 SCOTT                          Win7_Casa\jlchiappa            SCOTT  
                     SCOTT
  DEPT                                                                          
                                        TABLE
Win7_Casa\jlchiappa            Not Blocking None

 okdoc ?
 
   []s
   
     Chiappa
         

--- Em oracle_br@yahoogrupos.com.br, "J. Laurindo Chiappa" <jlchiappa@...> 
escreveu
>
>   Hmmm, peraí : "nunca vai sair" é absolutamente Falso : o lock que A está 
> mantendo (e que impede B de lockar o mesmo recurso) *** NÃO *** é Eterno, ele 
> VAI SIM ser liberado assim que A encerrar a transação, seja com COMMIT seja 
> com ROLLBACK, yes ??? Da mesma maneira, dizer que é "impossível identificar 
> quem está lockando registros de quem" sorry, mas afaik é Inverdade também : 
> via script é Plenamente Possível vc consultar quem está esperando pelo que, 
> aí não é impossível não vc localizar quem está com o lock para si, os outros 
> TODOS estão em espera por essa sessão, dado o cenário que vc descreve...
>   
>    O que é Questionável, podendo mesmo ser considerado uma FALHA no 
> aplicativo é esse comportamento de :
>    
>     1. deixar a transação que obteve o lock ficar ILIMITADAMENTE aberta, sem 
> nenhum tipo de timeout, nem de aviso ao Operador se a transação for 
> controlada pelo Usuário da aplicação e não for encerrada o mais logo possível
>       
>       e
>       
>       2. dado o fato 1. acima (de poder existir Transação sem controle 
> estrito de tempo), após a Aplicação corretamente usar o for update nowait 
> para testar se um recurso está lockado, quando detectar que um 
> registro/resource está lockado (recebendo o ORA-0054) a Aplicação ficar 
> tentando e retentando o lock INDEFINIDAMENTE é falha - o correto ao invés 
> seria LIMITAR a quantidade de vezes em que espera o lock ser liberado (via 
> LOOP ** não-eterno **, repetido uma qtdade FIXA de vezes) E/OU limitar o 
> período de tempo em que espera o lock já presente ser encerrado com o fim 
> datransação que o criou...
> 
>  Agora entendi, é uma falha de Controle/Tratamento pela Aplicação no 
> procedimento de LOCK NOWAIT, que em si está Corretíssimo e Não deveria causar 
> espanto algum, ok... 
>  
>   Muito bem, o que vc vai poder fazer aí a nível de banco de dados, Enquanto 
> a Aplicação não tem essa falha corrigida é fazer no banco de dados o que a 
> Aplicação não faz, ie, LIMITAR a duração de uma transação (e portanto limitar 
> o tempo que um lock pode existir), OU então eliminar esses casos, o que 
> poderia ser feito via :
> 
>   a) implementação algum tipo de timeout nas sessões (via PROFILE, talvez), 
> para que uma sessão A que obteve um lock num dado recurso NÂO fique com 
> transações abertas por tempo irrazoavelmente longo, assim limitando o tempo 
> que B fica esperando pelo lock
> 
> e/ou
> 
>   b) tendo um JOB no banco que a cada poucos x minutos consulta a V$SESSION 
> e/ou a DBA_LOCKS e/ou views de WAIT, e se detectar espera muito longa por 
> locks o JOB poderia mandar um e-mail para te avisar e/ou matar a sessão 
> incial que implantou o lock (REGISTRANDO essa ação nalgum lugar, é Claro), 
> coisa do tipo
> 
>   []s
> 
>     Chiappa
> 
> 
> --- Em oracle_br@yahoogrupos.com.br, JLSilva <jljlsilva@> escreveu
> >
> > Chiappa, o meu espanto é devido à lógica utilizada na aplicação.
> > Se o registro está lockado, o processo entra em um loop e tenta novamente 
> > executar exatamente o mesmo select for update nowait para lockar o registro.
> > O efeito cascata disso é que, ao fazer isto, a sessão A não libera os 
> > registros anteriores e continua tentando lockar novos registros que estão 
> > lockados pela sessão B.
> > Enquanto isso, a sessão B que está lockando outros registros, e em um 
> > determinado momento, a sessão B vai tentar lockar o registro que está 
> > lockado pela sessão A.
> > Se não fosse utilizado o "nowait" nesse select, ocorreria um deadlock, pois 
> > A está locando o registro 1, B está locando o registro 2, A tenta locar o 
> > registro 2 e B tenta locar o registro 1.
> > Mas, devido à forma que a aplicação foi construída, o deadlock nunca 
> > ocorre, e a aplicação nunca vai sair desse loop.
> > Agora, imagine isto ocorrendo com muitas sessões (mais de 10 sessões).
> > Acaba que tem várias sessões lockando registros, elas não liberam esses 
> > registros, e ficam tentando locar novos registros que já estão lockados por 
> > outras, e ficam nesse loop. Fica impossível identificar quem está lockando 
> > registros de quem.
> > Infelizmente, o fornecedor é daquele tipo difícil, e diz que "o sistema 
> > está funcionando em 200 outros locais". Ok, mas aqui está ocorrendo esse 
> > problema...
> > Mas, concordo com você. Desativar o nowait teria um resultado muito 
> > imprevisível para o funcionamento do rdbms como um todo.
> > 
> > On Mar 18, 2013, at 5:30 PM, "J. Laurindo Chiappa" <jlchiappa@> wrote:
> > 
> > >  Bom, vamos começar respondendo à sua pergunta : Não, em princípio afaik 
> > > (salvo alguma alteração PESADA, não-suportada e EXTREMAMENTE perigosa de 
> > > interferir no banco como um todo, tipo via parâmetros internos, OU então 
> > > jogando-se o parâmetro de compatibility lá embaixo pra alguma versão 
> > > antiga, etc ) no caso não há como vc alterar o comportamento do comando 
> > > "SELECT FOR UPDATE NOWAIT", não... Aliás, de modo geral, Não Há como vc 
> > > fazer um dado comando que está documentado agir assim ou assado agir de 
> > > outro jeito, não...
> > > 
> > > Isso respondido, observo que vc está "espantado" com a utilização, e nem 
> > > imagino porque : veja vc, é ABSOLUTAMENTE normal e documentado (vide 
> > > manual "Oracle® Database Advanced Application Developer's Guide" cap. 1 - 
> > > SQL Processing for Application Developers , e algumas entradas sobre 
> > > LOCKs no Concepts) que é EXATAMENTE ASSIM que vc "pergunta" se um 
> > > registro está lockado ou não : vc tenta fazer um lock com NOWAIT e se der 
> > > ORA-0054 ele tá lockado, se não der não está... Eu ABSOLUTAMENTE NÃO 
> > > ENTENDI a sua "admiração", os "!!!" que vc colocou na msg, sim ???? 
> > > Também Não Entendi porque vc quer mudar isso - é Absolutamente Normal que 
> > > um recurso (tabela/registro/whatever) possa ser acessado em modo 
> > > exclusivo, corretamente o teu Aplicativo CHECA isso, e vc quer remover 
> > > esse check ?? Não entendo porque - diga para nós EXATAMENTE o que vc quer 
> > > que a gente tenta sugerir algo....
> > > 
> > > []s
> > > 
> > >   Chiappa
> > > 
> > > 
> > > --- Em oracle_br@yahoogrupos.com.br, JLSilva <jljlsilva@> escreveu
> > >> 
> > >> Senhores, boa tarde.
> > >> Temos uma aplicação de terceiros (CHB) que faz "select ... for update 
> > >> ... NOWAIT".
> > >> Essa aplicação recebe o erro ORA-00054 e o tratamento que ela dá é: 
> > >> tenta o select novamente!!!!!!!
> > >> Com isso, não ocorre o deadlock, nem consigo saber exatamente quem é o 
> > >> bloqueador, pois há dezenas de sessões atualizando a mesma tabela.
> > >> Alguém aí sabe se é possível desativar o "nowait" através de algum 
> > >> parâmetro/configuração do banco?
> > >> Obrigado!
> > >> 
> > > 
> > > 
> > > 
> > > 
> > > ------------------------------------
> > > 
> > > --------------------------------------------------------------------------------------------------------------------------
> > >> Atenção! As mensagens do grupo ORACLE_BR são de acesso público e de 
> > >> inteira responsabilidade de seus remetentes.
> > > Acesse: http://www.mail-archive.com/oracle_br@yahoogrupos.com.br/ 
> > > --------------------------------------------------------------------------------------------------------------------------
> > >> Apostilas » Dicas e Exemplos » Função » Mundo Oracle » Package » 
> > >> Procedure » Scripts » Tutoriais - O GRUPO ORACLE_BR TEM SEU PROPRIO 
> > >> ESPAÇO! VISITE: http://www.oraclebr.com.br/  
> > > ------------------------------------------------------------------------------------------------------------------------
> > >  Links do Yahoo! Grupos
> > > 
> > >
> >
>


Responder a