Home > Java, Oracle > Como resolver Weblogic com Oracle ORA-01591 lock held by in-doubt distributed transaction

Como resolver Weblogic com Oracle ORA-01591 lock held by in-doubt distributed transaction

Essa semana tive muitos problemas no trabalho por causa desse ORA-01591, chegou ao ponto dele travar minha aplicação no weblogic em produção. Portanto decidi compartilhar a solução que custamos a chegar, inclusive o suporte da Oracle teve que ser ativado para conseguir essas informações. Importante:  reiniciar o banco NÃO limpa essas transações in-doubt.

Descrição

A descrição desse erro pode ser encontrada no site oficial http://ora-01591.ora-code.com/, simplificando esse problema ocorre quando uma transação distribuída perde seu coordenador de transação. Ou seja, o Oracle fica em dúvida sobre o que deve ser feito com a transação que agora está sem coordenador, assim ele mantém ativo o lock que essa transação estava fazendo no registro e se outra transação tentar alterar essa mesma linha o oracle lança o erro ORA-01591.

Se você caiu aqui procurando por esse erro você deve ter entendido o que eu expliquei acima, já que estará utilizando os recursos avançados como transação distribuída.

Solução

A solução para esse problema é forçar o rollback ou commit da transação para liberar os locks do banco. Eu recomendo o rollback para evitar inconsistências nas tabelas.

Bem para conseguir fazer um rollback da transação é preciso saber qual o transaction ID da transação que está segurando o lock. Existem duas possibilidades e em ambas é necessário ser SYS para executar:

Possibilidade 1

Fazer um select na sys.pending_trans$ ou na sys.pending_sessions$ para obter o local_tran_id, será um String como essa 166.5.1546.

Pronto, agora basta fazer o rollback com o comando:

rollback force ‘166.5.1546’;

Se não ocorrer nenhum erro, parabéns seu lock foi removido e sua aplicação deve voltar ao normal. Entretanto, se ocorreu algum erro dizendo que não encontrou essa transação, vá para a possibilidade 2.

Possibilidade 2

Nesse caso o problema é mais grave, pois sua transação nem está mais nas tabelas de controle do oracle. Foi nesse caso que eu esbarrei e a solução é mais complicada.

  • Passo 1: Fazer seguinte select para obter o número da transação:

SELECT KTUXEUSN, KTUXESLT, KTUXESQN, KTUXESTA Status, KTUXECFL Flags FROM x$ktuxe WHERE ktuxesta!=’INACTIVE’;

  • Passo 2: Agora some os campos da seguinte maneira (já pode fazer isso direto no select):

KTUXEUSN + ‘.’ + KTUXESLT + ‘.’ + KTUXESQN, isso vai te dar o número da transação no formato esperado166.5.1546

  • Passo 3: Temos que inserir esse valor nas tabelas de controle, sim isso mesmo! Tem que inserir nas tabelas internas do Oracle!

    INSERT INTO sys.pending_trans$
(local_tran_id, global_tran_fmt, global_oracle_id, state, status, session_vector, reco_vector, type#, fail_time, reco_time)
VALUES
(!!!SEU_ID_TRANSACAO, 306206, ‘XXXXXXX.12345.1.2.3’, ‘prepared’, ‘P’, HEXTORAW(‘00000001’), HEXTORAW(‘00000000’), 0, SYSDATE, SYSDATE);

INSERT INTO sys.pending_sessions$
VALUES
(!!!SEU_ID_TRANSACAO,1,HEXTORAW(‘05004F003A1500000104′),’C’, 0, 30258592,  ”, 146);

COMMIT;

  • Passo 4: executar o comando
    rollback force ‘166.5.1546’;
    COMMIT;
  • Passo 5: verificar se deu tudo certo e se os registros que você inseriu sumiram das tabelas sys.pending_trans$ e sys.pending_sessions$. Se sumiu o registro pode parar por aqui, problema resolvido, caso contrário tentar fazer o passo 6.
  • Passo 6: Execute o comando: dbms_transaction.purge_lost_db_entry(!!!SEU_ID_TRANSACAO);
    Faça as verificações do passo 5, se falhar tente fazer o passo 7.
  • Passo 7: Execute os deletes para limpar os registros fake:
    DELETE FROM sys.pending_trans$ WHERE local_tran_id = !!!SEU_ID_TRANSACAO;
    DELETE FROM sys.pending_sessions$ WHERE local_tran_id = !!!SEU_ID_TRANSACAO;

Nesse ponto sua transação deve ter sido liberada, senão funcionou contate o suporte da Oracle. Lembrando que reiniciar o banco NÃO limpa essas transações in-doubt

Categories: Java, Oracle Tags: , , ,
  1. Alex Hobi Gomes
    21/01/2013 at 11:01 am

    Parabéns cara, me ajudou muito.

  2. Juliana Gomes
    12/03/2013 at 2:49 pm

    esse tipo de situação a gente nunca mais esquece 🙂

  1. No trackbacks yet.

Leave a comment