Autonomous Transactions
Em uma ocasião recente, um colega ficou em dúvida sobre Autonomous Transactions. Este artigo visa dar algumas explicações à respeito, para tanto, antes de chegarmos ao ponto de Transação Autônoma, vamos dar um pequeno passo para trás e ver o que é uma TRANSAÇÃO.
O fato é: Há anos atrás, quando foi estabelecida a arquitetura chamada relacional para databases, uma das exigências estruturais criada foi a integridade transacional, ie : o SGBD Tem que permitir ao usuário enviar um conjunto de N comandos de manipulações de dados e é por conta do usuário indicar que o conjunto de comandos INTEIRO vai poder ser efetivado (via comando COMMIT) ou deve ser descartado (com o comando ROLLBACK). Para isso, o SGBD TEM que possuir mecanismos internos que permitam a qualquer momento esse encerramento de transação. Além disso, os dados manipulados dentro de uma transação não efetivada PRECISAM ser ‘invisíveis’/inacessíveis aos outros usuários/outras sessões do database (não pode NUNCA haver a chamada ‘leitura suja’, ie, dados ainda não confirmados serem lidos), e enquanto não ocorrer o encerramento da transação, os outros usuários/outras sessões TEM que enxergar os dados como estavam antes.
Isto exposto, aí fica simples de entender o conceito de Autonomous Transaction/Transação Autônoma, que é simplesmente uma rotina que é executada sob OUTRA transação, independente da transação que esteja aberta no momento. A maior vantagem disso são situações tais como INSERTs em tabelas de auditoria, que devem ser gravadas SEJA ou NÃO encerrada com sucesso a transação original.
Exemplo: Por necessidade de segurança/auditoria do negócio, digamos que sempre que se tentou alterar a coluna SAL da tabela EMP seja exigido guardar na tabela TB_ACESSOS_SAL.
- Primeiro, preciso ter a tabela de “Auditoria” criada
scott@DESENV:SQL>create table TB_ACESSOS_SAL(DT_ACESSo date, USERNAME varchar2(33));
Tabela criada.
- Depois crio uma trigger que faz DML : sem especificar uma Transação autônoma, o DML na tabela de Audit vai pertencer à mesma Transação relacionada com o UPDATE que disparou a trigger
scott@DESENV:SQL>create or replace trigger TRG_UPD_SAL after UPDATE OF SAL ON EMP for each row
2 BEGIN
3 insert into TB_ACESSOS_SAL values(sysdate, user);
4 END;
5 /
Gatilho criado.
- Executo um UPDATE, o que por sua vez dispara a trigger
scott@DESENV:SQL>update emp set sal=3001 where empno=7935;
1 linha atualizada.
- Transação é encerrada com “desfazimento”
scott@DESENV:SQL>rollback; Rollback concluído.
- O DML na tabela de Audit, como foi disparado na mesma transação encerrada, foi desfeito também
scott@DESENV:SQL>select * from TB_ACESSOS_SAL; não há linhas selecionadas
- Agora, vamos fazer o INSERT na tabela de audit numa transação separada
scott@DESENV:SQL>create or replace procedure GRAVA_AUD_UPD_SAL is 2 PRAGMA AUTONOMOUS_TRANSACTION; 3 BEGIN 4 insert into TB_ACESSOS_SAL values(sysdate, user); 5 commit; 6 END; 7 / Procedimento criado.
- Alterarei a trigger para chamar essa rotina AT
scott@DESENV:SQL>create or replace trigger TRG_UPD_SAL after UPDATE OF SAL ON EMP for each row 2 BEGIN 3 GRAVA_AUD_UPD_SAL; 4 END; 5 / Gatilho criado.
- Novamente, executo UPDATE que dispara a trigger
scott@DESENV:SQL>update emp set sal=3001 where empno=7935; 1 linha atualizada.
- MESMO que a transação original seja desfeita, a transação INDEPENDENTE não será desfeita
scott@DESENV:SQL>rollback; Rollback concluído. scott@DESENV:SQL>select * from TB_ACESSOS_SAL; DT_ACESSO USERNAME ------------------- ------------ 23/04/2021 10:54:32 SCOTT scott@DESENV:SQL>
O uso de Transação Autônoma para contorno das limitações de triggers de DML, como é sabido, as triggers disparadas após um DML (INSERT, UPDATE ou DELETE) em tabela possuem duas restrições: Primeiro, não podem conter comandos de encerramento de transação (seja COMMIT seja ROLLBACK) e segundo, não podem realizar nem SELECT nem DML na tabela à qual a trigger de DML está associada.
Uma opção para contornar tais restrições é o uso de Autonomous Transaction, com os comandos que violam as restrições contidos em um PL/SQL em modo de Autonomous Transactions. Há muitas outras possibilidades para isso (por exemplo, COMPOUND TRIGGERs) mas o uso de uma transação autônoma contendo os comandos desejados pode ser viável, também
Abraços

Profissional atuante há 31 anos na área de TI, dos quais 25 anos dedicados à tecnologia Oracle®, capacitado em Tuning, Instalação, Migração, Backup, Segurança e troubleshooting no RBDMS Oracle, bem como desenvolvimento e programação em PL/SQL, Java, shell scripting C, Oracle Forms e Oracle Reports.
Detentor de Qualificações de DBA Sênior, Analista e Desenvolvedor obtidas via atuação em empresas nas áreas de Finanças, Produção Industrial, Comércio e outras, Certificado como Oracle Database 11g Certified Implementation Specialist, Oracle Certificate Associate (OCA) 11g, IBM Certified Database Associate – DB2 10 Fundamentals, IBM Information Management DB2 10 Technical Professional v3 , IBM InfoSphere Guardium Technical Security Professional v1.
Atuação eventual (desde Out/95) como Instrutor Oracle em PL/SQL, Tuning e programação em Oracle Forms/Reports.
Excelente explicação! Parabéns!
Muito bom !
Eu precisei usar a transação autônoma quando precisei que um grupo de boleto gerasse numero sequenciais ( ter o mesmo efeito de uma sequencia) sem precisar bloquear e outras transações ficasse em LOCK esperando a geração do boleto em lote.
Excelente!
Muito bom