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

別のトランザクションのトランザクション分離レベルが競合しないフィルターでシリアル化できるのに、なぜTSQLステートメントブロックを挿入するのですか?

    テストシナリオの最初の問題は、テーブルにfirstnameの有用なインデックスがないことです。 。 2つ目は、テーブルが空であることです。

    キー範囲のロック から BOLで

    RangeS-Sを取得するのに適したインデックスはありません シリアル化可能なセマンティクスを保証するためにロックオンするSQLServerはテーブル全体をロックする必要があります。

    以下のように名の列のテーブルにクラスター化インデックスを追加して、実験を繰り返してみた場合...

    CREATE CLUSTERED INDEX [IX_FirstName] ON [dbo].[dummy] ([firstname] ASC)
    

    ...あなたはまだブロックされていることがわかります!

    適切なインデックスが現在存在し、実行プランは、クエリを満たすためにインデックスが検索されていることを示しています。

    次のコマンドを実行すると、その理由がわかります

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    
    BEGIN TRAN
    
    SELECT *
    FROM   dummy
    WHERE  firstname = 'abc'
    
    SELECT resource_type,
           resource_description, 
           request_mode
    FROM   sys.dm_tran_locks
    WHERE  request_session_id = @@SPID
    
    COMMIT 
    

    返品

    +---------------+----------------------+--------------+
    | resource_type | resource_description | request_mode |
    +---------------+----------------------+--------------+
    | DATABASE      |                      | S            |
    | OBJECT        |                      | IS           |
    | PAGE          | 1:198                | IS           |
    | KEY           | (ffffffffffff)       | RangeS-S     |
    +---------------+----------------------+--------------+
    

    SQL Serverは、クエリで指定した範囲を正確に範囲ロックするだけではありません。

    一意のインデックスの等式述語の場合、一致するキーがある場合は、任意のタイプの範囲ロックではなく、通常のロックが適用されます。

    一意でないシーク述語の場合、範囲内の一致するすべてのキーと、範囲の最後にある「次の」キー(またはffffffffffff)のロックを解除します。 「次の」キーが存在しない場合は無限大を表します)。 削除された「ゴースト」レコードも この範囲のキーロックで使用できます。

    ここで説明されているように 一意または非一意のインデックスのいずれかの等価述語の場合

    したがって、空のテーブルではSELECT それでも、インデックス全体をロックすることになります。以前にabcの間に行を挿入しておく必要があります およびlmn そうすれば、挿入は成功します。

    insert into dummy values('def', 'def')
    


    1. postgresqlの最大行数に関する制約を作成するにはどうすればよいですか?

    2. PostgreSQLで列のデータ型を確認する3つの方法

    3. Postgresがインデックスを使用しないのはなぜですか?

    4. PSQLスクリプト(bashスクリプトから供給)の変数として外部XMLファイルにアクセスする