O primeiro problema em seu cenário de teste é que a tabela não tem índice útil em
firstname
. A segunda é que a mesa está vazia. De Bloqueio de intervalo de chave em BOL
Não há índice adequado para obter
RangeS-S
locks on para garantir a semântica serializável, o SQL Server precisa bloquear a tabela inteira. Se você tentar adicionar um índice clusterizado na tabela na coluna do primeiro nome conforme abaixo e repetir o experimento...
CREATE CLUSTERED INDEX [IX_FirstName] ON [dbo].[dummy] ([firstname] ASC)
... você descobrirá que ainda está bloqueado!
Apesar do fato de que agora existe um índice adequado e o plano de execução mostra que ele é procurado para satisfazer a consulta.
Você pode ver o porquê executando o seguinte
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
Devoluções
+---------------+----------------------+--------------+
| resource_type | resource_description | request_mode |
+---------------+----------------------+--------------+
| DATABASE | | S |
| OBJECT | | IS |
| PAGE | 1:198 | IS |
| KEY | (ffffffffffff) | RangeS-S |
+---------------+----------------------+--------------+
O SQL Server não apenas remove um bloqueio de intervalo exatamente no intervalo especificado em sua consulta.
Para um predicado de igualdade em um índice exclusivo, se houver uma chave correspondente, ele usará apenas um bloqueio regular em vez de qualquer tipo de bloqueio de intervalo.
Para um predicado de busca não único ele retira bloqueios em todas as chaves correspondentes dentro do intervalo mais o "próximo" no final do intervalo (ou em
ffffffffffff
para representar o infinito se não existir nenhuma chave "próximo"). Até mesmo registros "fantasmas" excluídos
pode ser usado neste bloqueio de chave de intervalo. Conforme descrito aqui para um predicado de igualdade em um índice exclusivo ou não exclusivo
Então, com uma tabela vazia, o
SELECT
ainda acaba bloqueando todo o índice. Você também precisaria ter inserido anteriormente uma linha entre abc
e lmn
e então sua inserção seria bem-sucedida. insert into dummy values('def', 'def')