Ciekawy problem. To moje najlepsze przypuszczenie. Nie testowałem tego.
Ogólnie rzecz biorąc, wykształcone domysły postgresa dotyczące tego, jaki wpływ oświadczenia będą miały na dane, nie rozciąga się na logikę wyzwalania. Podczas wykonywania drugiej instrukcji postgres widzi ograniczenie klucza obcego i wie, że musi sprawdzić, czy przypisana (wstawiona) wartość jest poprawna, to znaczy, czy reprezentuje poprawny klucz w tabeli obcej. Możliwe jest, jakkolwiek zła praktyka, że wyzwalacz może mieć wpływ na ważność proponowanego klucza obcego (np. jeśli wyzwalacz usuwa rekordy).
(przypadek 1) Jeśli nie ma wyzwalacza, może przejrzeć dane (zarówno przed zatwierdzeniem, jak i w przygotowaniu do zatwierdzenia) i zdecydować, czy proponowana wartość jest gwarantowana. (przypadek 2) Jeśli nie ma ograniczenia FK, wyzwalacz nie może wpłynąć na ważność wstawienia, więc jest to dozwolone. (przypadek 3) Jeśli pominiesz detail_id=null
, nie ma zmian w aktualizacji, więc wyzwalacz nie uruchomi się, więc jego obecność jest nieistotna.
Staram się unikać zarówno ograniczeń FK, jak i wyzwalaczy, gdy tylko jest to możliwe. Moim zdaniem lepiej jest pozwolić, aby baza przypadkowo zawierała częściowo niepoprawne dane, niż zawiesić ją całkowicie, tak jak tutaj. Usunąłbym wszystkie ograniczenia i wyzwalacze FK i zmusił wszystkie operacje aktualizacji i wstawiania do działania za pomocą zapisanych funkcji, które wykonują walidację wewnątrz blokady begin/commit i obsługują nieprawidłowe/nieprawidłowe próby wstawienia/aktualizacji odpowiednio i natychmiast, zamiast wymuszać postgres do poczekaj na zatwierdzenie polecenia 1 przed podjęciem decyzji, czy polecenie 2 jest dozwolone.
Edytuj: zobacz to pytanie
Edytuj 2: Najbliższą rzeczą, jaką mogę znaleźć w oficjalnej dokumentacji dotyczącej czasu wyzwalania w odniesieniu do sprawdzania ograniczeń, jest to z dokumentacja wyzwalaczy
Jest to nieco niejasne, jeśli wyzwalacz, który ma miejsce przed sprawdzeniem ograniczeń, dotyczy sprawdzania ograniczeń innych transakcji. Niezależnie od przypadku, ten problem jest albo błędem, albo słabo udokumentowanym.