Oracle
 sql >> Database >  >> RDS >> Oracle

Come evitare l'errore ORA-04091 all'interno di un trigger

Potresti fare in modo che il grilletto su A faccia qualcosa per avvisare il grilletto su B che non ha bisogno di sparare. Ci sono vari desideri per impostare uno stato per una sessione. L'approccio più semplice possibile sarebbe quello di creare un pacchetto con una variabile booleana bypass_checks_on_b che hai impostato su TRUE prima di eseguire l'UPDATE su A, imposta su FALSE una volta UPDATE completa, quindi controlla lo stato di questa variabile nel trigger su B prima di eseguire le convalide. Potresti fare qualcosa di simile anche con una tabella temporanea o un contesto piuttosto che usare un pacchetto. In modo meno efficiente, potresti potenzialmente analizzare lo stack di chiamate all'interno del tuo trigger su B per vedere se il trigger su A è nello stack di chiamate, ma tenderebbe ad essere piuttosto brutto.

Sarei molto cauto su tutta questa architettura, però. Quando scopri di avere trigger su A che causano l'attivazione di trigger su B che vorrebbero interrogare A, è quasi sempre il caso che hai inserito troppa logica nei trigger e che saresti molto più servito muovendoti quella logica in un livello di stored procedure che può essere chiamato anziché le applicazioni che eseguono inserimenti o aggiornamenti diretti. Quando si inserisce troppa logica nei trigger, si finisce con un sistema che è molto difficile da capire perché non è ovvio dal codice dell'applicazione che tipo di effetti collaterali hanno le varie istruzioni. E finisci con un codice molto stateful in cui hai molti percorsi attraverso un singolo pezzo di codice a seconda del chiamante. Ciò significa quasi sicuramente che ci saranno stati in cui non testerai o non pensi a dove scoprirai che il tuo codice fa qualcosa di inaspettato. Tra avere un sacco di stato e avere una base di codice con un sacco di effetti collaterali, puoi creare molto rapidamente una base di codice che è essenzialmente non manutenibile.