Conteúdo voltado para banco de dados Oracle e SQL Server

Solucionando o erro ORA-01591 – lock held by in-doubt distributed transaction

O erro: ORA-01591: lock held by in-doubt distributed transaction, ou em um bom português ORA-01591: bloqueio retido pela transação distribuída 3251.6.3549 geralmente é causado por timeout entre as instâncias de um Oracle RAC.

A consulta por transações retidas ficam na tabela: DBA_2PC_PENDING. Um simples select nessa tabela retorna informações sobre as transações locais e globais:

SELECT LOCAL_TRAN_ID, GLOBAL_TRAN_ID,STATE,
‘EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘||””||LOCAL_TRAN_ID||””||’);’||chr(13)||’COMMIT;’
FROM DBA_2PC_PENDING
ORDER BY 1 ASC;

Para limpar as transações, basta executar o comando abaixo, onde o @local_tran_id é o campo LOCAL_TRAN_ID da tabela DBA_2PC_PENDING:

EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘@LOCAL_TRAN_ID’);
COMMIT;

Em alguns casos é preciso realizar o rollback da transação através do comando ROLLBACK FORCE ‘@LOCAL_TRAN_ID’, ficando o script completo dessa maneira:

ROLLBACK FORCE ‘@LOCAL_TRAN_ID’;
EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘@LOCAL_TRAN_ID’);
COMMIT;

Para automatizar essa limpeza podemos utilizar o seguinte script no crontab ou no Oracle Scheduler e agendar da forma como seu ambiente se comporta, podendo ser diario, semanal ou mensal:

declare
xid varchar2(22);
begin
for c1 in (select LOCAL_TRAN_ID FROM DBA_2PC_PENDING) loop
dbms_transaction.PURGE_LOST_DB_ENTRY(c1.LOCAL_TRAN_ID);
commit;
end loop;
end;

Importante: Em situações que não for possível purgar a transação via pacote DBMS, o procedimento poderá ser feito de forma manual executando os 3 deletes abaixo:

delete from
sys.pending_trans$
where
local_tran_id = ‘LOCAL_TRAN_ID’;

delete from
sys.pending_sessions$
where
local_tran_id = ‘LOCAL_TRAN_ID’;

delete from
sys.pending_sub_sessions$
where
local_tran_id = ‘LOCAL_TRAN_ID’;

commit;

 

É importante frisar que esse procedimento resolve os problemas das transações retidas e não elimina a causa raiz do problema, procure encontrar evidências no ALERT.LOG, no log do GRID para resolver o problema por completo.

 

Leonardo Pedroso

Leonardo Pedroso, é administrador de banco de dados, possui amplo conhecimento em Oracle 11g e 12c, com atuação em empresas de telecomunicações, bancos, seguradoras e órgãos do governo brasileiro prestando serviços especializados em banco de dados. Atua ativamente em comunidades técnicas através de fóruns, eventos, blog e palestras.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.