sql >> Databáze >  >> RDS >> Sqlserver

Je jeden příkaz SQL Server atomický a konzistentní?

Pracoval jsem za předpokladu, že jeden příkaz v SQL Server je konzistentní

Tento předpoklad je chybný. Následující dvě transakce mají identickou sémantiku zamykání:

STATEMENT

BEGIN TRAN; STATEMENT; COMMIT

Žádný rozdíl. Jednotlivé příkazy a automatické potvrzení nic nemění.

Takže sloučení veškeré logiky do jednoho prohlášení nepomůže (pokud ano, byla to náhoda, protože se změnil plán).

Pojďme problém vyřešit. SERIALIZABLE opraví nekonzistenci, kterou vidíte, protože zaručuje, že se vaše transakce budou chovat, jako by byly prováděny jednovláknově. Ekvivalentně se chovají, jako by byly provedeny okamžitě.

Dostanete se do slepé uličky. Pokud jste v pořádku se smyčkou opakování, v tomto bodě jste hotovi.

Chcete-li investovat více času, použijte rady pro zamykání, abyste si vynutili výhradní přístup k relevantním datům:

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
)

Nyní uvidíte sníženou souběžnost. To může být zcela v pořádku v závislosti na vaší zátěži.

Samotná povaha vašeho problému ztěžuje dosažení souběžnosti. Pokud pro to potřebujete řešení, museli bychom použít invazivnější techniky.

UPDATE můžete trochu zjednodušit:

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

Tím se zbavíte jednoho zbytečného spojení.



  1. PostgreSQL:problémy s kódováním ve Windows při použití nástroje příkazového řádku psql

  2. array_agg pro typy polí

  3. Oracle SQL pro změnu typu sloupce z čísla na varchar2, když obsahuje data

  4. Oracle vloží z výběru do tabulky s více sloupci