Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Por que inserir o bloco de instrução TSQL quando o nível de isolamento da transação para outra transação é serializável com filtro não conflitante?


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')