Stai utilizzando una transazione autonoma per aggirare il fatto che un trigger non può interrogare la sua tabella stessa. Ti sei imbattuto nel famigerato errore di tabella mutante e hai scoperto che dichiarare il trigger come transazione autonoma fa scomparire l'errore.
Nessuna fortuna per te però, questo non risolve affatto il problema:
- In primo luogo, qualsiasi logica di transazione viene persa. Non puoi ripristinare le modifiche su
suscription_fact
tabella, sono impegnati , mentre la transazione principale non è e potrebbe essere annullata. Quindi hai anche perso l'integrità dei tuoi dati. - Il trigger non può vedere la nuova riga perché la nuova riga non è ancora stata salvata! Poiché il trigger viene eseguito in una transazione indipendente, non può vedere le modifiche non vincolate apportate dalla transazione principale:ti imbatterai in risultati completamente errati.
Questo è il motivo per cui non dovresti mai fare alcuna logica di business nelle transazioni autonome. (ci sono applicazioni legittime ma sono quasi interamente limitate alla registrazione/debug).
Nel tuo caso dovresti:
- Aggiorna la tua logica in modo che non necessiti di interrogare la tua tabella (aggiornando
suscription_fact
solo se la nuova riga è più recente del vecchio valore memorizzato inid_date_unsuscription
). - Dimentica l'utilizzo della logica aziendale nei trigger e utilizza una procedura che aggiorna correttamente tutte le tabelle o utilizza una vista perché qui abbiamo un chiaro caso di dati ridondanti.
- Utilizza una soluzione alternativa che funzioni effettivamente (di Tom Kyte) .
Consiglio vivamente di utilizzare (2) qui. Non utilizzare i trigger per codificare la logica aziendale. Sono difficili da scrivere senza bug e ancora più difficili da mantenere. L'utilizzo di una procedura garantisce che tutto il codice rilevante sia raggruppato in un unico luogo (un pacchetto o una procedura), facile da leggere e seguire e senza conseguenze impreviste.