テストシナリオの最初の問題は、テーブルに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')