Você está usando uma transação autônoma para contornar o fato de que um gatilho não pode consultar sua própria tabela. Você se deparou com o infame erro de tabela mutante e descobriu que declarar o gatilho como uma transação autônoma faz com que o erro desapareça.
Sem sorte para você, porém, isso não resolve o problema:
- Primeiro, qualquer lógica de transação é perdida. Você não pode reverter as alterações no
suscription_fact
tabela, eles estão comprometidos , enquanto sua transação principal não é e pode ser revertida. Então você também perdeu a integridade dos seus dados. - O gatilho não pode ver a nova linha porque a nova linha ainda não foi confirmada! Como o gatilho é executado em uma transação independente, ele não pode ver as alterações não confirmadas feitas pela transação principal:você encontrará resultados completamente errados.
É por isso que você nunca deve fazer nenhuma lógica de negócios em transações autônomas. (existem aplicativos legítimos, mas eles são quase inteiramente limitados ao registro/depuração).
No seu caso, você deve:
- Atualize sua lógica para que ela não precise consultar sua tabela (atualizando
suscription_fact
somente se a nova linha for mais recente que o valor antigo armazenado emid_date_unsuscription
). - Esqueça o uso de lógica de negócios em gatilhos e use um procedimento que atualize todas as tabelas corretamente ou use uma visualização porque aqui temos um caso claro de dados redundantes.
- Use uma solução alternativa que realmente funciona (por Tom Kyte) .
Eu recomendaria fortemente usar (2) aqui. Não use gatilhos para codificar a lógica de negócios. Eles são difíceis de escrever sem bugs e ainda mais difíceis de manter. O uso de um procedimento garante que todo o código relevante seja agrupado em um só lugar (um pacote ou um procedimento), fácil de ler e seguir e sem consequências imprevistas.