sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Deadlock spørgsmål

SELECT'er kan ikke deadlock med andre SELECT, fordi de kun erhverver delte låse. Du siger, at vi bør overveje, at disse SELECT'er nu 'kræver eksklusive læselåse', men det er ikke muligt for os at overveje, fordi 1) der ikke er sådan noget som en exlusive read lock og 2) læser får ikke eksklusive låse.

Men du stiller et mere generelt spørgsmål, om simple udsagn kan slå fast. Svaret er et klart, rungende JA . Låse anskaffes ved udførelse, analyseres ikke på forhånd og sorteres derefter i en eller anden rækkefølge. Det ville være umuligt for motoren på forhånd at kende de nødvendige låse, fordi de afhænger af de faktiske data på disken, og at læse de data, motoren skal bruge for at ... låse dataene.

Dødlåse mellem simple udsagn (SELECT vs. UPDATE eller SELECT vs. DELETE) på grund af forskellig indeksadgangsrækkefølge er ret almindelige og meget nemme at undersøge, diagnosticere og rette. Men bemærk, at der altid er en skriveoperation involveret, da læsninger ikke kan blokere hinanden. Til denne diskussion bør tilføjelse af et UPDLOCK- eller XLOCK-tip til et SELECT betragtes som en skrivning. Du behøver ikke engang et JOIN, et sekundært indeks kan meget vel introducere adgangsordreproblemet, der fører til dødvande, se Læs/skriveadlock .

Og endelig skriver du SELECT FROM A JOIN B eller skrive SELECT FROM B JOIN A er fuldstændig irrelevant. Forespørgselsoptimeringsværktøjet er frit til at omarrangere adgangsrækkefølgen, som den finder passende, den faktiske tekst i forespørgslen påtvinger på ingen måde rækkefølgen for udførelse.

Opdateret

Jeg er bange for, at der ikke er nogen opskrift på småkager. Løsningen vil afhænge fra sag til sag. I sidste ende er dødvande i databaseapplikationer et faktum. Jeg forstår, at dette kan lyde absurd, som i 'vi landede på månen, men vi kan ikke skrive en korrekt databaseapplikation', men der er stærke faktorer på spil, som stort set garanterer, at applikationer i sidste ende vil støde på dødvande. Heldige dødvande er de nemmest at håndtere fejl, enkelt læs tilstanden igen, anvend logikken, omskriv den nye tilstand. Når det nu er sagt, er der nogle gode praksisser, der dramatisk kan reducere hyppigheden af ​​dødvande, ned til det punkt, hvor de næsten er forsvundet:

  • Prøv at have et ensartet adgangsmønster til Writes . Har klart definerede regler, der siger ting såsom 'en transaktion skal altid tabeller i denne rækkefølge:Customers -> OrderHeaders -> OrderLines .' Bemærk, at ordren skal adlydes i en transaktion . Grundlæggende skal du rangere alle tabeller i dit skema og angiv, at alle opdateringer skal ske i rækkefølge. Dette bunder i sidste ende ned til kodedisciplin for den enkelte bidragyder, der skriver koden, da den skal sikre, at den skriver opdateres i den rigtige rækkefølge i en transaktion.
  • Reducer varigheden af skriverier. Den sædvanlige visdom er sådan:I begyndelsen af ​​transaktionen skal du udføre alle læsninger (læs den eksisterende tilstand), derefter behandle logikken og beregne nye værdier, og derefter skrive alle opdateringer i slutningen af ​​transaktionen. Undgå et mønster som 'læs->skriv->logik->læs->skriv', gør i stedet 'læs->læs->logik->skriv->skriv'. Selvfølgelig består det sande håndværk i, hvordan man håndterer faktiske, reelle, individuelle sager, når man tilsyneladende skal skal gøre skriver midt i transaktionen. En særlig bemærkning her skal siges om en bestemt type transaktion:dem, der er drevet af en kø, som per definition starter deres aktivitet ved at udkø (=en skrivning) fra køen. Disse applikationer var altid notorisk svære at skrive og tilbøjelige til fejl (specielt deadlocks), heldigvis er der måder at gøre det på, se Brug af tabeller som køer .
  • Reducer mængden af ​​læsninger. Tabelscanninger er den mest udbredt årsag til dødvande. Korrekt indeksering vil ikke kun eliminere deadlocks, men kan også øge ydeevnen i processen.
  • Snapshot-isolering . Dette er det tætteste, du kommer på en gratis frokost med hensyn til at undgå dødvande. Jeg satte det med vilje til sidst, fordi det kan maske andre problemer (som ukorrekt indeksering) i stedet for at løse dem.

Forsøger at løse dette problem med en LockCustomerByXXX tilgang jeg er bange for ikke virker. Pessimistisk låsning skalerer ikke. Optimistisk samtidighed opdateringer er den vej at gå, hvis du vil have nogen form for anstændig præstation.



  1. dvale dialekt for oracle 12c

  2. Kan ikke konvertere MySQL.DateTime til System.DateTime med 0000-00-00 00:00:00 værdier

  3. Syntaksfejl under forsøg på at kalde en Oracle-pakke ved hjælp af ODBC i C#

  4. ADF-filtertabel baseret på trævalg