Utilização da Diretiva PRAGMA AUTONOMOUS_TRANSACTION (Oracle)

Em determinados momentos de nossa vida profissional nos deparamos com problemas muitas vezes inusitados. Este mini-artigo mostra a utilização da diretiva PRAGMA AUTONOMOUS_TRANSACTION em um exemplo real. Apesar de pouco usual, a utilização da mesma pode ser útil em diversos casos.

Em determinados momentos de nossa vida profissional nos deparamos com problemas muitas vezes inusitados. Este mini-artigo mostra a utilização da diretiva PRAGMA AUTONOMOUS_TRANSACTION em um exemplo real. Apesar de pouco usual, a utilização da mesma pode ser útil em diversos casos.

Quem nunca teve que adaptar alguma FUNCTION ou PROCEDURE oracle para refletir mudanças nas regras de algum sistema? Muitas vezes, esta mudança pode gerar problemas aparentemente insolúveis. Um bom exemplo aconteceu comigo.

No sistema que desenvolvo (em conjunto com diversas outras pessoas) existia uma função que era invocada em várias partes do código e que retornava códigos de validação (pequenas strings codificadas). Este tipo de implementação funcionou muito bem até que a quantidade de códigos retornados ficou exageradamente grande e a função passou a não retornar nada.

Como esta função era invocada em todo o sistema, não era viável mudar sua assinatura (seus parâmetros de entrada e nem seu tipo de retorno). Assim sendo, a idéia que tivemos foi criar uma tabela temporária que pudesse armazenar as strings e na chamada da função o insert fosse dado nesta tabela.

Neste momento nos deparamos com o problema. Ao fazer SELECT <nome_da_funcao> FROM DUAL, o Oracle levantava a seguinte exceção:

ORA-14551: cannot perform a DML operation inside a query

Para que fosse possível realizar o preenchimento da tabela temporária na função acima, fomos obrigados a utilizar uma instrução do Oracle que funciona como uma diretiva de compilação e que é pouco usual:

PRAGMA AUTONOMOUS_TRANSACTION;

Esta instrução (PRAGMA) funciona como uma diretiva de compilação para o ORACLE, que passa a tratar esta função como um código independente da transação principal que esteja ocorrendo. Assim, o COMMIT realizado na função, não afeta outras transações abertas. Esse mecanismo também possibilitou que o INSERT realizado na tabela temporária por esta função pudesse ser realizado, mesmo que a função seja executada em uma instrução de SELECT, o que, normalmente,não seria permitido pelo Oracle (nestes casos é normal ele levantar a exceção ORA-14551: cannot perform a DML operation inside a query).

Para saber mais sobre a instrução PRAGMA AUTONOMOUS_TRANSACTION, basta acessar http://stanford.edu/dept/itss/docs/oracle/10g/appdev.101/b10807/13_elems002.htm

Espero que este mini-artigo seja útil de alguma forma. Grande abraço e até a próxima.

Artigos relacionados