sql >> データベース >  >> RDS >> Sqlserver

存在する場合は、ELSE INSERT を選択してから選択します

    2 つの同時クライアントが同じ fieldValue を 2 回挿入しないようにするには、トランザクションでこれを行う必要があります:

    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
    

    ダブルチェック ロック も使用できます ロックのオーバーヘッドを減らす

    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
    

    ISOLATION LEVEL SERIALIZABLE が必要な理由については、シリアル化可能なトランザクション内にいる場合、テーブルにヒットする最初の SELECT によって、レコードがあるべき場所をカバーする範囲ロックが作成されるため、このトランザクションが終了するまで他の誰も同じレコードを挿入できません。

    ISOLATION LEVEL SERIALIZABLE がないと、デフォルトの分離レベル (READ COMMITTED) は読み取り時にテーブルをロックしないため、SELECT と UPDATE の間で誰かが挿入できます。 READ COMMITTED 分離レベルのトランザクションでは、SELECT がロックされません。 REPEATABLE READS を使用したトランザクションは、レコード (見つかった場合) をロックしますが、ギャップはロックしません。



    1. SQL Server スキーマの利点

    2. javafxのデータベースから表示するデータのフィルタリング

    3. dockercomposeで起動するときにテーブルpostgresqlを作成する方法

    4. SQLで特定のユーザーの各会話で最新のメッセージを取得するにはどうすればよいですか?