Pierwszym problemem w twoim scenariuszu testowym jest to, że tabela nie ma użytecznego indeksu dla firstname
. Po drugie, stół jest pusty.
Od Blokowanie zakresu kluczy w BOL
Nie ma odpowiedniego indeksu do pobrania RangeS-S
blokuje się, aby zagwarantować semantykę serializacji, SQL Server musi zablokować całą tabelę.
Jeśli spróbujesz dodać klastrowy indeks w tabeli w kolumnie z imieniem, jak poniżej i powtórz eksperyment...
CREATE CLUSTERED INDEX [IX_FirstName] ON [dbo].[dummy] ([firstname] ASC)
... przekonasz się, że nadal jesteś zablokowany!
Pomimo faktu, że odpowiedni indeks już istnieje, a plan wykonania pokazuje, że jest on poszukiwany w celu spełnienia zapytania.
Możesz zobaczyć dlaczego, uruchamiając następujące
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
Zwroty
+---------------+----------------------+--------------+
| resource_type | resource_description | request_mode |
+---------------+----------------------+--------------+
| DATABASE | | S |
| OBJECT | | IS |
| PAGE | 1:198 | IS |
| KEY | (ffffffffffff) | RangeS-S |
+---------------+----------------------+--------------+
SQL Server nie tylko blokuje zakres dokładnie w zakresie określonym w zapytaniu.
W przypadku predykatu równości na unikalnym indeksie, jeśli istnieje pasujący klucz, przyjmie on po prostu zwykłą blokadę, a nie jakikolwiek rodzaj blokady zakresu.
W przypadku nieunikalnego predykatu wyszukiwania usuwa blokady na wszystkich pasujących kluczach w zakresie plus „następny” na końcu zakresu (lub na ffffffffffff
do reprezentowania nieskończoności, jeśli „następny” klucz nie istnieje). Nawet usunięte rekordy „duchów”
może być używany w tym zakresie blokowania klawiszy.
Zgodnie z opisem dla predykatu równości na unikalnym lub nieunikalnym indeksie
Więc z pustą tabelą SELECT
nadal kończy się blokowaniem całego indeksu. Musisz również wcześniej wstawić wiersz między abc
i lmn
i wtedy Twoja wstawka się powiedzie.
insert into dummy values('def', 'def')