Zajímavý problém. To je můj nejlepší odhad. Nic z toho jsem netestoval.
Obecně řečeno, postgresovo vzdělané hádání o tom, jaký vliv budou mít příkazy na data, nezasahuje do spouštěcí logiky. Při provádění druhého příkazu postgres vidí omezení cizího klíče a ví, že musí zkontrolovat, zda je přiřazovaná (vkládaná) hodnota platná, to znamená, zda představuje platný klíč v cizí tabulce. Je možné, jakkoli špatná praxe, že spouštěč může mít vliv na platnost navrhovaného cizího klíče (např. když spouštěč maže záznamy).
(případ 1) Pokud neexistuje žádný spouštěč, může se podívat na data (jak před potvrzením, tak připravená pro potvrzení) a rozhodnout, zda je navrhovaná hodnota zaručeně platná. (případ 2) Pokud neexistuje žádné omezení FK, pak spouštěč nemůže ovlivnit platnost vložení, takže je povoleno. (případ 3) Pokud vynecháte detail_id=null
, aktualizace se nijak nezměnila, takže spoušť se nespustí, takže jeho přítomnost je irelevantní.
Snažím se vyhnout jak omezením FK, tak spouštěčům, kdykoli je to možné. Podle mého názoru je lepší nechat databázi náhodně obsahovat částečně nesprávná data, než ji nechat úplně viset, jak to vidíte zde. Upustil bych od všech FK omezení a spouštěčů a vynutil bych, aby všechny operace aktualizace a vložení fungovaly prostřednictvím uložených funkcí, které provádějí ověření uvnitř zámku zahájení/potvrzení a zpracují nesprávné/neplatné pokusy o vložení/aktualizaci vhodně a okamžitě, než abych nutil postgres, aby počkejte na potvrzení příkazu 1, než se rozhodnete, zda je příkaz 2 povolen.
Upravit: viz tuto otázku
Úprava 2: Nejbližší věc, kterou mohu najít oficiální dokumentaci týkající se načasování spouštěčů ve vztahu ke kontrole omezení, je tato z spouštěcí dokumenty
To je trochu nejasné, pokud se spouštěč, ke kterému dojde před kontrolou omezení, vztahuje na kontrolu omezení jiných transakcí. Ať je to jakkoli, tento problém je buď chyba, nebo je špatně zdokumentován.