Pular para o conteúdo
  • Este tópico contém 6 respostas, 3 vozes e foi atualizado pela última vez 9 anos, 1 mês atrás por Avatar de C-S-RC-S-R.
Visualizando 7 posts - 1 até 7 (de 7 do total)
  • Autor
    Posts
  • #107279
    Avatar de C-S-RC-S-R
    Participante

      Ola caros amigos de profissão.
      Feliz ano novo para todos.

      Hoje estou com um problema de deadlock e gostaria de uma ajuda.

      Pelo que pude entender esta ocorrendo um lock de tabela “X”.
      Alguem pode me dizer o pq?
      A tabela tem indexes nas FKs.

      Desde ja agradeço

      Segue parte do trace.

      Deadlock graph:
      ---------Blocker(s)-------- ---------Waiter(s)---------
      Resource Name process session holds waits process session holds waits
      TX-000a000d-000e7459 176 2246 X 237 3159 X
      TX-001b0006-000ed7e8 237 3159 X 176 2246 X

      session 2246: DID 0001-00B0-0107DA42 session 3159: DID 0001-00ED-00A27AA9
      session 3159: DID 0001-00ED-00A27AA9 session 2246: DID 0001-00B0-0107DA42

      Rows waited on:
      Session 2246: obj - rowid = 000CC8D1 - AADMjRAAcAAKTjHABG
      (dictionary objn - 837841, file - 28, block - 2701511, slot - 70)
      Session 3159: obj - rowid = 000CC8D1 - AADMjRAAcAAKTjHABF
      (dictionary objn - 837841, file - 28, block - 2701511, slot - 69)

      ----- Information for the OTHER waiting sessions -----
      Session 3159:
      sid: 3159 ser: 475 audsid: 575693931 user: 148/P9_USER
      flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
      flags2: (0x40009) -/-/INC
      pid: 237 O/S info: user: oracle, term: UNKNOWN, ospid: 28118
      image: oracle@lacbra800lnx054
      client details:
      O/S info: user: was, term: unknown, ospid: 1234
      machine: lacbra800lnx033 program: JDBC Thin Client
      application name: JDBC Thin Client, hash value=2546894660
      current SQL:
      update P9.CASAM_EVENTO_RF_SELIC set INDC_COMPARTILHADA=:1, COD_CTA_CLEARING=:2, DT_EVENTO=:3, DIFERENCA_VALORES=:4, COD_EVENTO_RECEBIDO_SELIC=:5, COD_PAP=:6, PU_SELIC=:7, PU_SISTEMA=:8, QTDE_SELIC=:9, QTDE_SISTEMA=:10, TP_EVEN_CAMARA=:11, VALOR_SELIC=:12, VALOR_SISTEMA=:13 where COD_CASAM_EVENTO_RF_SELIC=:14

      ----- End of information for the OTHER waiting sessions -----

      Information for THIS session:

      ----- Current SQL Statement for this session (sql_id=1fr4ah4bj601u) -----
      update P9.CASAM_EVENTO_RF_SELIC set INDC_COMPARTILHADA=:1, COD_CTA_CLEARING=:2, DT_EVENTO=:3, DIFERENCA_VALORES=:4, COD_EVENTO_RECEBIDO_SELIC=:5, COD_PAP=:6, PU_SELIC=:7, PU_SISTEMA=:8, QTDE_SELIC=:9, QTDE_SISTEMA=:10, TP_EVEN_CAMARA=:11, VALOR_SELIC=:12, VALOR_SISTEMA=:13 where COD_CASAM_EVENTO_RF_SELIC=:14

      #107281
      Avatar de caadecarvalhocaadecarvalho
      Participante

        @C-S-R

        Deadlocks são quando duas transações travam umas as outras esperando por recurso. Normalmente acontece quando duas sessões distintas executam comandos nos mesmos registros.

        Exemplo, imagine que a sessão 1 atualiza o registro A da tabela T1 e não efetua o commit, então a sessão 2 atualiza o registro B da tabela T2 e também não efetua o commit. Até este ponto, o comportamento está normal, porém o problema maior de deadlock pode acontecer quando a sessão 1 tentar atualizar o registro B da tabela T2 e a sessão 2 tentar atualizar o registro A da tabela T1.

        Neste momento, ambas as transações estarão esperando pela liberação do recurso que nunca serão liberados. Pelo trace que você gerou, podemos evidenciar que a sessão 2246 e 3159 foram as causadoras deste comportamento. O Oracle consegue tratar esta situação automaticamente, efetuando rollback em alguma das sessões. Porém este tipo de erro, evidencia um mal comportamento da aplicação e deve ser corrigido a fim de evitá-lo.

        Abraços.

        #107283
        Avatar de C-S-RC-S-R
        Participante

          @caadecarvalho

          Vlw pela ajuda.

          Então, a aplicação não deveria atualizar os mesmos registros.
          A Aplicação esta executando em parallelo varios desses updates mas de ids diferentes.

          No trace fala que o problema é um update, se é um update deveria dar lock na linha.
          Porém o trace fala de lock “exclusive” que é um lock de tabela.

          Se o Oracle esta fazendo lock de tabela realmente vai dar deadlock.

          Então minha duvida é.

          O Oracle esta fazendo lock na tabela? Se esta, pq?
          É aquele update que esta ocasionando o lock ou preciso procurar o rowid que esta no trace?

          At
          Cesar Moraes

          #107284
          Avatar de rmanrman
          Participante

            @C-S-R

            Muita gente acha que é o UPDATE que faz o LOCK, de certa forma é, mas temos que abstrair um pouco mais, e analisar a transação como um todo, não apenas o comando que iniciou o LOCK, o LOCK só será liberado após o COMMIT ou ROLLBACK.

            Você deve analisar e identificar qual funcionalidade do sistema que causou o DEADLOCK, e analisar a transação. LOCK/DEADLOCK é gerado pelo mau gerenciamento da transação, ou seja, não está sendo feito o uso do COMMIT/ROLLBACK de forma adequada.

            #107285
            Avatar de C-S-RC-S-R
            Participante

              @rman

              Obrigado pela resposta.

              Sim a funcionalidade da aplicação que esta fazendo lock esta em analise com a equipe de desenvolvimento, eles estão verificando se em alguma parte pode estar ocorrendo o lock.

              O que estou tentando entender são as informações do trace para poder dar mais informações pro pessoal de desenvolvimento.

              Meu problema mesmo é entender o trace.


              TX-000a000d-000e7459 176 2246 X 237 3159 X
              TX-001b0006-000ed7e8 237 3159 X 176 2246 X

              Nessa parte o X indica um lock de tabela?
              Quais as situações que o Oracle poderia fazer um lock de tabela? A aplicação ta fazendo um monte de insert e update


              Session 2246: obj - rowid = 000CC8D1 - AADMjRAAcAAKTjHABG
              (dictionary objn - 837841, file - 28, block - 2701511, slot - 70)
              Session 3159: obj - rowid = 000CC8D1 - AADMjRAAcAAKTjHABF
              (dictionary objn - 837841, file - 28, block - 2701511, slot - 69)

              Esses hexdecimais são os objetos locados? pq 2?

              E no caso do update pelo que entendi, não da pra ter certeza se é ele que esta causando o deadlock, e precisaria de uma analise da transação como um todo.

              Essas informações são para passar pra equipe poder encontrar o problema.

              At
              Cesar Moraes

              #107287
              Avatar de rmanrman
              Participante

                @C-S-R

                Vou ter dar um exemplo de mau gerenciamento de transação. Vamos supor que temos um processo de atualização da lista de preços dos produtos de um supermercado. Pense grande, temos 30 mil produtos que estão divididos em várias categorias. Cada categoria de produto vai aplicar um regra de negócio exclusiva para fazer o aumento do preço.

                --1 MINUTO PARA O CALCULO
                --UPDATE NO PRECO DO PRODUTO COM LOCK DE LINHA
                --2 MINUTOS PARA O CALCULO
                --INSERT EM UMA TABELA DE LOG
                

                Desta forma todo o processo está dentro de apenas 1 transação. Repare que demora 1 minuto para fazer o calculo do preço por produto. O COMMIT é feito após o LOOP, o LOCK aplicado no primeiro UPDATE é mantido até o ultimo UPDATE executado, pois o LOCK só é liberado após o COMMIT. Está claro o mau gerenciamento da transação.

                A solução adequada é colocar o COMMIT dentro do LOOP, mantendo a transação garantindo a consistência.

                --1 MINUTO PARA O CALCULO
                --UPDATE NO PRECO DO PRODUTO COM LOCK DE LINHA
                --2 MINUTOS PARA O CALCULO
                --INSERT EM UMA TABELA DE LOG
                

                A transação que garante a consistência é fazer o INSERT, o UPDATE e o COMMIT.

                Feito isso ainda pode acontecer LOCK? Sim, repare que o calculo para o log demora 2 minutos. Isso quer dizer que vai existir um LOCK de 2 minutos. Repare que o calculo do preço do produto não influencia pois está antes do LOCK de linha, o problema está no calculo para o log que é feito depois do LOCK de linha.

                A solução é otimizar o calculo do LOG diminuindo o tempo do LOCK.

                E se eu aplicar um COMMIT após o UPDATE e um COMMIT após o INSERT? ERRADO, desta forma você quebrou a transação em 2, havendo a possibilidade de gerar dados inconsistentes. O INSERT dos dados só deve existir se o UPDATE foi executado.

                #107296
                Avatar de C-S-RC-S-R
                Participante

                  Conseguimos achar o problema.

                  Realmente o problema estava no UPDATE que o trace mostrou. Ficou bem mais fácil achar o problema com um ponto de partida, verificar a transação inteira não era viável.

                  O Caso do lock de tabela não foi descoberto.

                  Agradeço a todos pela ajuda

                Visualizando 7 posts - 1 até 7 (de 7 do total)
                • Você deve fazer login para responder a este tópico.
                plugins premium WordPress