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 dívida 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 e altera 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.
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:
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;
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!
Te vejo no próximo post, tchau!