Transação distribuída

Detectando e resolvendo.Olá DBA! Em especial o amigo Danilo Delbone do DBA Brasil, um dos tantos fóruns e grupos de Oracle que participo e que fez uma pergunta via Whatsapp a respeito de um assunto interessante que é transação distribuída.

Bem, primeiramente uma breve explicação do que seria uma transação distribuída.
Antes pera lá que preciso explicar algo: na verdade o problema não é a transação distribuída e sim as transações que ficam pendentes de commit ou rollback ocasionando lock no banco de dados, o qual entende que o dado ainda está aguardando ser “comitado” ou “rolbackado” (nossa esse nome eu não conhecia, inventei agora. rsrsrs) e não libera alteração no bloco em questão. Este é o mecanismo fantástico de controle do Oracle, que um dia falaremos mais a fundo.

Ok! Sei que o você e o Danilo podem estar perguntando agora: “Mas onde entra a transação distribuída? O que ela é de fato?”
Alguns ambientes, onde temos diversas aplicações integradas porém residindo em bancos de dados diferentes, é comum encontrar transações que são feitas em um banco porém foram comandadas de outro ambiente.
Isso se torna possível através de um objeto de banco de dados chamado de DBLINK. Com ele é possível efetuar transações de um banco para outro através de um link criado.
O problema começa quando algumas vezes e por motivos diversos, acontecem falhas na conexão entre eles. Quando isso acontece pode ser que alguma transação fique, como eu falo sempre “pendurada”.rsrsrs. Isso mesmo! Ela fica pendente de encerramento.
Quando isso ocorre precisa ser feito um commit ou rollback force para liberar os recursos.

Certa vez eu trabalhava em uma grande empresa de telefonia onde este erro era até comum, digo, acontecia com certa frequência, como lá tudo tinha que ser muito dinâmico o tempo todo, lá utilizávamos um script para descobrir e proceder o force.

declare
  cursor cv_pending is
    SELECT * FROM DBA_2PC_PENDING
      WHERE fail_time < (SYSDATE-5/1440); — falha ocorreu a menos de 5 minutos atrás
begin
  FOR x IN cv_pending LOOP
     DBMS_OUTPUT.PUT_LINE(”);
     DBMS_OUTPUT.PUT_LINE(‘rollback force ”’ || x.local_tran_id || ”’;’);
     DBMS_OUTPUT.PUT_LINE(‘COMMIT;’);
     DBMS_OUTPUT.PUT_LINE(‘EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(”’ || x.local_tran_id || ”’);’);
     DBMS_OUTPUT.PUT_LINE(‘COMMIT;’);
    END LOOP;
end;
/

Para o script acima ele irá detectar, fazer o rollback force e liberar o objeto.
Posso dizer pra você que este script eu utilizei muitas vezes e com certeza funciona.
Manter transações entre diversos bancos de dados funciona mas deve ser muito bem estudada para evitar problemas futuros.

Bem amigo, era isso que tinha pra hoje, espero que tenham gostado, Danilo, mais uma vez obrigado por ter perguntado e inspirado o post de hoje. rsrsrs.
Lembrando que espero você e todos os amigos no projeto DBA.
Não deixe de visitar no facebook: facebook.com/raulfdba

Grande abraço a todos! UM excelente semana e FOCO NA META!!!

Sobre raul andrade

DBA e Instrutor Oracle, apaixonado pela minha família e por ensinar.
Esta entrada foi publicada em DBA Oracle, Scripts e marcada com a tag , , . Adicione o link permanente aos seus favoritos.

Deixe uma resposta