Deadlocks: Oppdaging og forebygging
Forstå hvordan deadlocker oppstår, hvordan Postgres oppdager dem, og utform regler for låserekkefølge som hindrer dem.
Deadlocks: Oppdaging og forebygging er en gratis leksjon i SQL Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i SQL Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i SQL Academy inneholder totalt 4 leksjoner.
Hva er en deadlock?
To transaksjoner holder hver sin lås som den andre ønsker — ingen av dem kan fortsette. Databasen oppdager syklusen og avbryter én av transaksjonene.
En klassisk deadlock
Tx A låser rad 1, og Tx B låser rad 2. A ber om rad 2, og B ber om rad 1. Fastlåst.
-- Tx A:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- waiting for B...
-- Tx B:
BEGIN;
UPDATE accounts SET balance = balance - 50 WHERE id = 2;
UPDATE accounts SET balance = balance + 50 WHERE id = 1;
-- waiting for A...
-- ERROR: deadlock detectedPostgreSQL oppdager deadlocks
Ved hvert deadlock_timeout (standard er 1 sekund) kontrollerer PostgreSQL om det finnes låsesykluser. Hvis en syklus oppdages, avbrytes én transaksjon med feilkode 40P01.
ERROR: deadlock detected
DETAIL: Process 1234 waits for ShareLock on transaction 5678 ...Regel for låserekkefølge
Løsningen: Hent alltid låser i samme rekkefølge i alle kodebaner.
-- Always update the lower id first:
UPDATE accounts SET balance = balance - 100 WHERE id = LEAST(:from, :to);
UPDATE accounts SET balance = balance + 100 WHERE id = GREATEST(:from, :to);Deadlocks på belastede rader
Raske oppdateringer av de samme belastede radene utløser ofte låseventing, ikke deadlocks. Bruk køer, partisjoner den belastede raden, eller serialiser oppdateringer i applikasjonskoden.
FOR UPDATE låser rader ved lesing
Skaff skrivelåser ved lesing for å unngå overraskelser senere:
BEGIN;
SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
-- both rows locked in id order
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;Hopp over låste rader
For køtabeller, mønsteret «hent en valgfri tilgjengelig rad»:
SELECT * FROM jobs
WHERE status = 'pending'
ORDER BY created_at
LIMIT 1
FOR UPDATE SKIP LOCKED;
-- skips rows other workers have lockedNOWAIT
Feil umiddelbart i stedet for å vente:
SELECT * FROM accounts WHERE id = 1 FOR UPDATE NOWAIT;
-- ERROR: could not obtain lock on row in relation "accounts"Diagnostisere deadlocks
Øk log_lock_waits og ta med deadlock-konteksten i loggen. Loggoppføringen viser begge transaksjonene og spørringene deres.
Løkke for nye forsøk i applikasjonen
Deadlocks kan håndteres — prøv den avbrutte transaksjonen på nytt:
for (let attempt = 0; attempt < 3; attempt++) {
try {
await runTransaction();
break;
} catch (e) {
if (e.code === '40P01') continue; // deadlock
throw e;
}
}Reduser låseomfanget
Forkort transaksjonene — alle berørte rader forblir låst til COMMIT. Ikke utfør HTTP-kall eller langvarige beregninger i en transaksjon.
Indekser fremmednøkler for å unngå låseeskalering
Når du sletter en overordnet rad, kontrolleres hver underordnede rad. Uten en FK-indeks innebærer dette et fullstendig tabellskann OG radlåser. Indekser hver FK-kolonne.
Oppsummering
Deadlocks oppstår — utform systemet slik at de minimeres.
- Hent låser i en konsekvent rekkefølge
- Bruk FOR UPDATE tidlig for å uttrykke intensjon
- SKIP LOCKED for køer
- Prøv på nytt ved deadlock-feil (40P01)
- Hold transaksjonene korte
Hurtigsjekk
Hva er det mest pålitelige designprinsippet for å forhindre deadlocks?
Lær deg SQL med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 46
- Leksjoner
- 183
Ofte stilte spørsmål
Er leksjonen «Deadlocks: Oppdaging og forebygging» gratis?
Ja – hele teksten i «Deadlocks: Oppdaging og forebygging» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av SQL Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i SQL Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Deadlocks: Oppdaging og forebygging»?
Forstå hvordan deadlocker oppstår, hvordan Postgres oppdager dem, og utform regler for låserekkefølge som hindrer dem. Du øver på SQL Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med SQL Academy?
Ingen tidligere erfaring er nødvendig. SQL Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «Deadlocks: Oppdaging og forebygging»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne SQL Academy-leksjonen?
Ja. Alle SQL Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- ACID-egenskaper og anomalier
- Isolasjonsnivåer: READ COMMITTED, REPEATABLE READ, SERIALIZABLE
- Deadlocks: Oppdaging og forebygging
- Optimistisk kontra pessimistisk låsing