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

Er en enkelt SQL Server-sætning atomart og konsistent?

Jeg har arbejdet under den antagelse, at en enkelt sætning i SQL Server er konsistent

Den antagelse er forkert. De følgende to transaktioner har identisk låsesemantik:

STATEMENT

BEGIN TRAN; STATEMENT; COMMIT

Ingen forskel overhovedet. Enkeltudsagn og auto-commits ændrer ikke noget.

Så det hjælper ikke at samle al logik i én erklæring (hvis det gør, var det ved et uheld, fordi planen ændrede sig).

Lad os løse det aktuelle problem. SERIALIZABLE vil rette den inkonsekvens, du ser, fordi det garanterer, at dine transaktioner opfører sig, som om de blev udført enkelt-trådet. Tilsvarende opfører de sig, som om de blev henrettet med det samme.

Du vil få dødvande. Hvis du er ok med en genforsøgsløkke, er du færdig på dette tidspunkt.

Hvis du vil investere mere tid, skal du anvende låsetip for at tvinge eksklusiv adgang til de relevante data:

UPDATE Gifts  -- U-locked anyway
SET GivenAway = 1
WHERE GiftID = (
   SELECT TOP 1 GiftID
   FROM Gifts WITH (UPDLOCK, HOLDLOCK) --this normally just S-locks.
   WHERE g2.GivenAway = 0
    AND (SELECT COUNT(*) FROM Gifts g2 WITH (UPDLOCK, HOLDLOCK) WHERE g2.GivenAway = 1) < 5
   ORDER BY g2.GiftValue DESC
)

Du vil nu se reduceret samtidighed. Det kan være helt fint afhængigt af din belastning.

Selve karakteren af ​​dit problem gør det svært at opnå samtidighed. Hvis du har brug for en løsning til det, er vi nødt til at anvende mere invasive teknikker.

Du kan forenkle OPDATERING en smule:

WITH g AS (
   SELECT TOP 1 Gifts.*
   FROM Gifts
   WHERE g2.GivenAway = 0
    AND (SELECT COUNT(*) FROM Gifts g2 WITH (UPDLOCK, HOLDLOCK) WHERE g2.GivenAway = 1) < 5
   ORDER BY g2.GiftValue DESC
)
UPDATE g  -- U-locked anyway
SET GivenAway = 1

Dette fjerner én unødvendig joinforbindelse.



  1. Web2py – Migrering fra SQLite til MySQL

  2. Rails 3.1:Forespørgsel efter postgres inden for et tidsinterval

  3. Sådan omdøbes en JSON-nøgle i SQL Server (T-SQL)

  4. VLDB'er i de 20-teenagere:You're Gonna Need A Bigger ...