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

Confuso sobre UPDLOCK, HOLDLOCK


Por que UPDLOCK bloquearia seleções? A Matriz de Compatibilidade de Bloqueio mostra claramente N para a disputa S/U e U/S, como em Sem conflito .

Quanto à dica HOLDLOCK, a documentação afirma:

HOLDLOCK:É equivalente a SERIALIZÁVEL. Para obter mais informações, consulte SERIALIZABLE mais adiante neste tópico.

...

SERIALIZABLE:... A varredura é executada com a mesma semântica de uma transação em execução no nível de isolamento SERIALIZABLE...

e o tópico Nível de isolamento da transação explica o que significa SERIALIZABLE:

Nenhuma outra transação pode modificar os dados que foram lidos pela transação atual até que a transação atual seja concluída.

Outras transações não podem inserir novas linhas com valores de chave que cairiam no intervalo de chaves lidas por qualquer instrução na transação atual até que a transação atual seja concluída.

Portanto, o comportamento que você vê é perfeitamente explicado pela documentação do produto:
  • UPDLOCK não bloqueia SELECT nem INSERT simultâneos, mas bloqueia qualquer UPDATE ou DELETE das linhas selecionadas por T1
  • HOLDLOCK significa SERALIZABLE e, portanto, permite SELECTS, mas bloqueia UPDATE e DELETES das linhas selecionadas por T1, também como qualquer INSERT no intervalo selecionado por T1 (que é a tabela inteira, portanto qualquer inserir).
  • (UPDLOCK, HOLDLOCK):sua experiência não mostra o que bloquearia além do caso acima, ou seja, outra transação com UPDLOCK em T2 :
    SELECT * FROM dbo.Test WITH (UPDLOCK) WHERE ...
  • TABLOCKX não precisa de explicações

A verdadeira questão é o que você está tentando alcançar ? Brincar com dicas de bloqueio sem uma compreensão absoluta de 110% da semântica de bloqueio é implorar por problemas ...

Após a edição do OP:

Eu gostaria de selecionar linhas de uma tabela e evitar que os dados dessa tabela sejam modificados enquanto estou processando.

Você deve usar um dos níveis de isolamento de transação mais altos. REPEATABLE READ impedirá que os dados lidos sejam modificados. SERIALIZABLE impedirá que os dados que você lê sejam modificados e novos dados sejam inseridos. Usar níveis de isolamento de transação é a abordagem correta, em vez de usar dicas de consulta. Kendra Little tem um belo pôster explicando os níveis de isolamento.