Per chiunque cerchi su Google e cerchi di capire perché la loro tabella di rilascio (o elimina la chiave esterna o aggiunge la chiave esterna) è rimasta bloccata per molto tempo:
PostgreSQL (Ho esaminato le versioni da 9.4 a 13) I vincoli di chiave esterna vengono effettivamente implementati utilizzando trigger su entrambe le estremità della chiave esterna .
Se hai una tabella azienda (id come chiave primaria) e una tabella bank_account (id come chiave primaria, company_id come chiave esterna che punta a company.id), allora ci sono in realtà 2 trigger sulla tabella bank_account e anche 2 trigger sull'azienda tabella.
nome_tabella | tempistica | nome_trigger | nome_funzione |
---|---|---|---|
conto_bancario | DOPO L'AGGIORNAMENTO | RI_ConstraintTrigger_c_1515961 | RI_FKey_check_upd |
conto_bancario | DOPO L'INSERIMENTO | RI_ConstraintTrigger_c_1515960 | RI_FKey_check_ins |
azienda | DOPO L'AGGIORNAMENTO | RI_ConstraintTrigger_a_1515959 | RI_FKey_noaction_upd |
azienda | DOPO L'ELIMINAZIONE | RI_ConstraintTrigger_a_1515958 | RI_FKey_noaction_del |
La creazione iniziale di tali trigger (durante la creazione della chiave esterna) richiede il blocco SHARE ROW EXCLUSIVE su tali tabelle (in passato era il blocco ACCESS EXCLUSIVE nella versione 9.4 e precedenti). Questo blocco non è in conflitto con i "blocchi di lettura dei dati", ma entrerà in conflitto con tutti gli altri blocchi, ad esempio un semplice INSERT/UPDATE/DELETE nella tabella dell'azienda.
L'eliminazione di tali trigger (quando si elimina la chiave esterna o l'intera tabella) richiede il blocco ACCESS EXCLUSIVE su quelle tabelle. Questo blocco è in conflitto con ogni altro blocco!
Quindi immagina uno scenario, in cui hai una transazione A in esecuzione che prima ha eseguito un semplice SELECT dalla tabella dell'azienda (facendo in modo che mantenga un blocco ACCESS SHARE per la tabella dell'azienda fino a quando la transazione non viene confermata o annullata) e ora sta facendo un altro lavoro per 3 minuti. Si tenta di eliminare la tabella bank_account nella transazione B. Ciò richiede il blocco ACCESS EXCLUSIVE, che dovrà attendere fino a quando il blocco ACCESS SHARE viene rilasciato prima. Inoltre, tutte le altre transazioni, che desiderano accedere alla tabella dell'azienda (solo SELEZIONA, o forse INSERT/UPDATE/DELETE), verrà messo in coda per attendere il blocco ACCESS EXCLUSIVE, che è in attesa del blocco ACCESS SHARE.
Le transazioni di lunga durata e le modifiche DDL richiedono una gestione delicata.