Oradata

PL/SQL Transações Autônomas

PL/SQL Transações Autônomas

Olá, normalmente nos posts que escrevo, sempre acabo falando de assuntos voltados para DBAs (até mesmo porque eu sou um rsrsrs), mas por muitas vezes nos meus treinamentos de SQL e PL/SQL os alunos acabam por me cobrar posts voltados para o processo de desenvolvimento, confesso que escrevo pouco ou quase nada a esse respeito, mas prometo pagar essa divida com vocês a partir de agora, escrevendo artigos úteis para desenvolvedores, até mesmo porque eu já fui um e gostava muito de programar, sendo assim vamos lá.

Hoje vamos falar de transações autônomas, que são aquelas famosas transações que acontecem de maneira independente, ou seja, uma transação principal se inicia e implicitamente dispara um outra transação. Para dar um exemplo mais claro, imagine uma situação onde devemos guardar registros de auditoria dentro de uma aplicação. Neste caso uma transação principal do usuário será iniciada, alterar um registro na tabela de funcionários por exemplo. Ao executar essa alteração na tabela de funcionários, uma trigger dispara e insere em uma tabela de auditoria que “fulano” alterou informações do funcionário “X” tal dia tal hora.

Neste caso, uma transação não pode atrapalhar a outra, se a transação principal sofrer um rollback, a transação autônoma não pode fazer parte deste rollback, caso contrário o processo de auditoria estaria comprometido, e o inverso também é verdadeiro, se houver algum erro no processo de registro na tabela de auditoria, você pode não querer atrapalhar a transação principal do usuário.

lnpls028

Pois bem, como fazemos isso dentro do banco de dados? Como informo para o banco de dados que existe esse “isolamento” entre as transações? Para isso usamos um comando chamado “PRAGMA AUTONOMOUS_TRANSACTION” esse comando informa ao compilador em tempo de “compilação” (e não de “execução”) que essas transações estão relacionadas, porém de maneira autônoma, ou seja uma não pode influenciar o comportamento da outra.

O comando “PRAGMA AUTONOMOUS_TRANSACTION” pode ser informado em qualquer parte da sessão declarativa de seu código, mas para ter um código mais limpo e legível procure colocar sempre no início. Abaixo alguns exemplos:

Em um bloco anonimo:

DECLARE
PRAGMA AUTONOMOUS_TRANSACTION -- <<< Olha ele aí!;
emp_id NUMBER(6);
amount NUMBER(6,2);
BEGIN
emp_id := 200;
amount := 200;
UPDATE employees SET salary = salary - amount WHERE employee_id = emp_id;
COMMIT;
END;
/

Em uma trigger:
CREATE OR REPLACE TRIGGER audit_sal
AFTER UPDATE OF salary ON employees FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION; -- <<< Olha aí, outro exemplo!
BEGIN
INSERT INTO emp_audit VALUES( :old.employee_id, SYSDATE,
:new.salary, :old.salary );
COMMIT;
END;
/

Conclusão: Trabalhar com transações autônomas traz muitas vantagens no processo de desenvolvimento, você consegue de certa forma fazer com que dois objetos trabalhem em sincronismo, mas sem que um afete as funcionalidades do outro, conseguindo então encapsular e modularizar as funcionalidades no seu código para automatizar tarefas, transações autônomas não geram disputas por recursos como lock e dead lock por exemplo.

Então é isso aí, foi um artigo curto, mas acredito que pode ser útil, em breve mais artigos para desenvolvedores e DBAs é claro!

Forte abraço e até a próxima!

Douglas Paiva de Sousa

2 thoughts on “PL/SQL Transações Autônomas

  1. FATIMA

    VI alguns exemplos com log. COlocando na trigger o logo é gravado independente do regsitro ser gravado ou nao.
    Gostaria de saber: se der uma exceção na trigger e a trigger tem a PRAGMA AUTONOMOUS_TRANSACTION , o principal é gravado?

    1. Douglas Paiva de Sousa Post author

      Olá Fátima,
      Se houver erro na transação autônoma uma a tendencia é que a transação principal lance uma exception também, porque olhando do ponto de vista lógico, a transação autônoma só acontece por causa da transação principal.

      Atenciosamente,
      Douglas Paiva de Sousa

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *