PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PSQLException e problema di blocco quando il trigger è stato aggiunto alla tabella

Problema interessante. Questa è la mia migliore ipotesi. Non ho testato nulla di tutto ciò.

In generale, l'ipotesi plausibile di Postgres su quale effetto avranno le affermazioni sui dati non si estende alla logica del trigger. Quando esegue la seconda istruzione, postgres vede il vincolo di chiave esterna e sa che deve controllare se il valore assegnato (inserito) è valido, cioè se rappresenta una chiave valida nella tabella esterna. È possibile, per quanto sia una cattiva pratica, che il trigger possa avere un effetto sulla validità della chiave esterna proposta (ad es. se il trigger elimina i record).

(caso 1) Se non è presente alcun trigger, può guardare i dati (sia pre-commit che staged for commit) e decidere se il valore proposto è garantito valido. (caso 2) Se non esiste un vincolo FK, il trigger non può influire sulla validità dell'inserimento, quindi è consentito. (caso 3) Se ometti detail_id=null , non ci sono modifiche nell'aggiornamento, quindi il trigger non si attiva, quindi la sua presenza è irrilevante.

Cerco di evitare sia i vincoli FK che i trigger quando possibile. È meglio, secondo me, lasciare che il database contenga accidentalmente dati parzialmente errati, quindi bloccarlo completamente, come stai vedendo qui. Rilascerei tutti i vincoli e i trigger FK e costringerei tutte le operazioni di aggiornamento e inserimento a funzionare tramite funzioni memorizzate, che eseguono la convalida all'interno di un blocco di avvio/commit e gestiscono i tentativi di inserimento/aggiornamento errati/non validi in modo appropriato e immediato, anziché forzare postgres a attendi che il comando 1 venga eseguito prima di decidere se il comando 2 è consentito.

Modifica: vedi questa domanda

Modifica 2: La cosa più vicina che posso trovare alla documentazione ufficiale sui tempi dei trigger relativi al controllo dei vincoli è questa da attiva i documenti

Questo è un po' poco chiaro, se il trigger che si verifica prima del controllo del vincolo si applica al controllo del vincolo di altre transazioni. In ogni caso, questo problema è un bug o è scarsamente documentato.