sql >> Database >  >> RDS >> Sqlserver

INDIEN BESTAAT, SELECTEER DAN ANDERS INSERT EN SELECTEER DAN

U moet dit in transactie doen om ervoor te zorgen dat twee gelijktijdige clients niet twee keer dezelfde fieldValue invoegen:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
    DECLARE @id AS INT
    SELECT @id = tableId FROM table WHERE [email protected]
    IF @id IS NULL
    BEGIN
       INSERT INTO table (fieldValue) VALUES (@newValue)
       SELECT @id = SCOPE_IDENTITY()
    END
    SELECT @id
COMMIT TRANSACTION

u kunt ook Double-checked_locking">Double-checked_locking gebruiken om vergrendeling overhead te verminderen

DECLARE @id AS INT
SELECT @id = tableID FROM table (NOLOCK) WHERE [email protected]
IF @id IS NULL
BEGIN
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRANSACTION
        SELECT @id = tableID FROM table WHERE [email protected]
        IF @id IS NULL
        BEGIN
           INSERT INTO table (fieldValue) VALUES (@newValue)
           SELECT @id = SCOPE_IDENTITY()
        END
    COMMIT TRANSACTION
END
SELECT @id

Wat betreft waarom ISOLATIENIVEAU SERIALISEERBAAR nodig is, wanneer u zich in een serialiseerbare transactie bevindt, creëert de eerste SELECT die de tafel raakt een bereikvergrendeling die de plaats bedekt waar het record zou moeten zijn, zodat niemand anders hetzelfde record kan invoegen totdat deze transactie eindigt.

Zonder ISOLATIENIVEAU SERIALIZABLE zou het standaard isolatieniveau (LEZEN COMMITTED) de tabel niet vergrendelen tijdens het lezen, dus tussen SELECT en UPDATE zou iemand nog steeds kunnen invoegen. Transacties met het isolatieniveau READ COMMITTED zorgen er niet voor dat SELECT wordt vergrendeld. Transacties met HERHAALBARE LEZEN vergrendelen het record (indien gevonden), maar niet het gat.



  1. Het gegevenstype van een kolom wijzigen in SQL Server (T-SQL)

  2. Log4Net werkt op Dev-machine, mislukt bij implementatie op gedeelde host (met dezelfde db/connstring)

  3. Zoek uit of een tafel een DELETE heeft op CASCADE

  4. MySQL 5.5 externe-sleutelbeperking mislukt wanneer externe sleutel bestaat