For alle, der googler og prøver at forstå, hvorfor deres drop-tabel (eller drop fremmednøgle eller tilføje fremmednøgle) har siddet fast i lang tid:
PostgreSQL (Jeg så på version 9.4 til 13) fremmednøglebegrænsninger implementeres faktisk ved hjælp af triggere i begge ender af fremmednøglen .
Hvis du har en virksomhedstabel (id som primærnøgle) og en bankkontotabel (id som primærnøgle, virksomheds-id som fremmednøgle, der peger på virksomhed.id), så er der faktisk 2 triggere på bankkontotabellen og også 2 triggere på virksomheden tabel.
tabelnavn | timing | trigger_name | funktionsnavn |
---|---|---|---|
bankkonto | EFTER OPDATERING | RI_ConstraintTrigger_c_1515961 | RI_FKey_check_upd |
bankkonto | EFTER INDSÆTNING | RI_ConstraintTrigger_c_1515960 | RI_FKey_check_ins |
virksomhed | EFTER OPDATERING | RI_ConstraintTrigger_a_1515959 | RI_FKey_noaction_upd |
virksomhed | EFTER SLETNING | RI_ConstraintTrigger_a_1515958 | RI_FKey_noaction_del |
Indledende oprettelse af disse triggere (når du opretter foreing-nøglen) kræver SHARE ROW EXCLUSIVE-lås på disse tabeller (det plejede at være ACCESS EXCLUSIVE-lås i version 9.4 og tidligere). Denne lås er ikke i konflikt med "datalæselåse", men vil være i konflikt med alle andre låse, for eksempel en simpel INSERT/OPDATERING/SLET i firmatabel.
Sletning af disse triggere (når du taber fremmednøglen eller hele bordet) kræver EKSKLUSIV ADGANG lås på disse borde. Denne lås er i konflikt med hver anden lås!
Så forestil dig et scenarie, hvor du har en transaktion A kørende, der først lavede en simpel SELECT from company table (som fik den til at holde en ACCESS SHARE-lås for virksomhedstabellen, indtil transaktionen er forpligtet eller rullet tilbage) og nu udfører noget andet arbejde for 3 minutter. Du forsøger at droppe bankkontotabellen i transaktion B. Dette kræver ACCESS EXCLUSIVE-lås, som skal vente, indtil ACCESS SHARE-låsen frigives først. Derudover alle andre transaktioner, som ønsker at få adgang til firmatabellen (bare VÆLG, eller måske INSERT/UPDATE/DELETE), vil stå i kø for at vente på ACCESS EXCLUSIVE-låsen, som venter på ACCESS SHARE-låsen.
Langvarige transaktioner og DDL-ændringer kræver skånsom håndtering.