sql >> Databasteknik >  >> RDS >> PostgreSQL

PSQLE Undantag och låsproblem när trigger läggs till i tabellen

Intressant problem. Detta är min bästa gissning. Jag har inte testat något av det.

Generellt sett sträcker sig postgres välutbildade gissningar om vilken effekt uttalanden kommer att ha på data inte till triggerlogik. När den andra satsen körs, ser postgres den främmande nyckel-begränsningen och vet att den måste kontrollera om värdet som tilldelas (infogas) är giltigt, det vill säga om det representerar en giltig nyckel i den främmande tabellen. Det är möjligt, oavsett hur dålig praxis än är, att utlösaren kan ha en effekt på giltigheten av den främmande nyckel som föreslås (t.ex. om utlösaren tar bort poster).

(fall 1) Om det inte finns någon trigger kan den titta på data (både pre-commit och staged for commit) och avgöra om det föreslagna värdet är garanterat giltigt. (fall 2) Om det inte finns någon FK-begränsning kan utlösaren inte påverka giltigheten av infogningen, så det är tillåtet. (fall 3) Om du utelämnar detail_id=null , det finns ingen förändring i uppdateringen så utlösaren aktiveras inte, så dess närvaro är irrelevant.

Jag försöker undvika både FK-begränsningar och triggers när det är möjligt. Det är bättre, enligt min mening, att låta databasen av misstag innehålla delvis felaktiga data då att låta den hänga sig helt, som du ser här. Jag skulle släppa alla FK-begränsningar och utlösare och tvinga alla uppdaterings- och infogningsoperationer att fungera via lagrade funktioner, som utför validering i ett start/commit-lås, och hantera felaktiga/ogiltiga insättnings-/uppdateringsförsök på lämpligt sätt och omedelbart, snarare än att tvinga postgres att vänta på att kommando 1 ska utföras innan du bestämmer om kommando 2 är tillåtet.

Redigera: se denna fråga

Redigera 2: Det närmaste jag kan hitta officiell dokumentation kring tidpunkten för triggers i förhållande till kontrollen av begränsningar är detta från utlöser dokument

Detta är lite oklart, om utlösandet sker före begränsningskontrollen gäller begränsningskontroll av andra transaktioner. Oavsett vilket är det här problemet antingen ett fel eller dåligt dokumenterat.




  1. Hitta skillnaden mellan tidsstämplar i sekunder i PostgreSQL med JOOQ

  2. postgreSQL - psql \i :hur man kör skript i en given sökväg

  3. Kunde inte ladda filen eller sammansättningen 'MySql.Data, Version=6.8.3.0 eller något av dess beroenden. Systemet kan icke finna den specificerade filen

  4. mysql-fråga:SELECT DISTINCT column1, GROUP BY column2