" Escalonamento de bloqueio " é como o SQL lida com o bloqueio para atualizações grandes. Quando o SQL muda muitas linhas, é mais eficiente para o mecanismo de banco de dados receber menos bloqueios maiores (por exemplo, tabela inteira) em vez de bloquear muitas coisas menores (por exemplo, bloqueios de linha).
Mas isso pode ser problemático quando você tem uma tabela enorme, porque bloquear uma tabela inteira pode bloquear outras consultas por um longo tempo. Essa é a desvantagem: muitos bloqueios de granularidade pequena são mais lentos que menos (ou um) bloqueios de granulação grossa, e ter várias consultas bloqueando diferentes partes de uma tabela cria a possibilidade de conflito se um processo estiver aguardando no outro.
Existe uma opção no nível da tabela LOCK_ESCALATION
, nova no SQL 2008, que permite o controle da escalação de bloqueios. O padrão "TABLE" permite que os bloqueios sejam escalados até o nível da tabela. DISABLE evita o escalonamento de bloqueios para a tabela inteira na maioria dos casos. AUTO permite bloqueios de tabela, exceto se a tabela for particionada; nesse caso, os bloqueios são feitos apenas no nível da partição. Veja esta postagem no blog para obter mais informações.
Suspeito que o IDE adicione essa configuração ao recriar uma tabela porque TABLE é o padrão no SQL 2008. Observe que LOCK_ESCALATION não é suportado no SQL 2005, portanto, você precisará removê-lo se tentar executar o script em um Instância de 2005. Além disso, como TABLE é o padrão, você pode remover com segurança essa linha ao executar novamente seu script.
Observe também que, no SQL 2005 antes que essa configuração estivesse presente, todos os bloqueios podiam ser escalados para o nível da tabela - em outras palavras, "TABLE" era a única configuração no SQL 2005.
CREATE TABLE
porque a tabela ainda não existe, portanto não há nada para bloquear.ALTER TABLE
instruções separadas . PrimeiroALTER TABLE ADD column
, depoisGO
, depois segundoALTER TABLE SET LOCK_ESCALATION=TABLE
, depois segundoGO
. Então,LOCK_ESCALATION
é definido após a coluna ser adicionada. Qual o sentido de defini-lo após o fato? Essas duasALTER TABLE
instruções são agrupadas em uma transação, mas ainda assim a coluna é adicionada antes daLOCK_ESCALATION
definição. Acho que vou aprofundar um pouco mais e escrever outra resposta.Você pode verificar se precisa incluir a instrução LOCK_ESCALATION em seu script comparando esse valor antes e depois de executar a parte principal do seu script:
No meu caso, alterar a tabela para eliminar ou adicionar uma restrição não parece modificar esse valor.
fonte
A resposta de Justin Grant explica o que a
LOCK_ESCALATION
configuração faz em geral, mas perde um detalhe importante e não explica por que o SSMS gera o código que a define. Especialmente, parece muito estranho que issoLOCK_ESCALATION
seja definido como uma última declaração no script.Fiz alguns testes e aqui está o meu entendimento do que está acontecendo aqui.
Versão curta
A
ALTER TABLE
instrução que adiciona, elimina ou altera uma coluna implica implicitamente um bloqueio de modificação de esquema (SCH-M) na tabela, que nada tem a ver com aLOCK_ESCALATION
configuração de uma tabela.LOCK_ESCALATION
afecta o comportamento de bloqueio durante as instruções DML (INSERT
,UPDATE
,DELETE
, etc.), e não durante as instruções de DDL (ALTER
). O bloqueio SCH-M é sempre um bloqueio de todo o objeto de banco de dados, tabela neste exemplo.Provavelmente é de onde vem a confusão.
O SSMS adiciona a
ALTER TABLE <TableName> SET (LOCK_ESCALATION = ...)
declaração ao seu script em todos os casos, mesmo quando não é necessário. Nos casos em que essa instrução é necessária, ela é adicionada para preservar a configuração atual da tabela, não para bloquear a tabela de alguma maneira específica durante a alteração no esquema da tabela. que ocorre nesse script.Em outras palavras, a tabela é bloqueada com o bloqueio SCH-M na primeira
ALTER TABLE ALTER COLUMN
instrução, enquanto todo o trabalho de alteração do esquema da tabela é realizado. A últimaALTER TABLE SET LOCK_ESCALATION
declaração não afeta. Ela afeta apenas futuros instruções DML (INSERT
,UPDATE
,DELETE
, etc.) para a tabela.À primeira vista, parece que
SET LOCK_ESCALATION = TABLE
ter algo a ver com o fato de estarmos alterando a tabela inteira (estamos alterando seu esquema aqui), mas é enganoso.Versão longa
Ao alterar a tabela em alguns casos, o SSMS gera um script que recria a tabela inteira e, em alguns casos mais simples (como adicionar ou soltar uma coluna), o script não recria a tabela.
Vamos pegar esta tabela de exemplo como exemplo:
Cada tabela possui uma
LOCK_ESCALATION
configuração, definidaTABLE
por padrão. Vamos mudar aqui:Agora, se eu tentar alterar o
Col1
tipo no designer da tabela SSMS, o SSMS gerará um script que recria a tabela inteira:Você pode ver acima que ele define
LOCK_ESCALATION
para a tabela recém-criada. O SSMS faz isso para preservar a configuração atual da tabela. O SSMS gera essa linha, mesmo que o valor atual da configuração seja oTABLE
valor padrão . Apenas para ser seguro, explícito e evitar possíveis problemas futuros, se no futuro esse padrão mudar, eu acho. Isso faz sentido.Neste exemplo, é realmente necessário gerar a
SET LOCK_ESCALATION
instrução, porque a tabela é criada novamente e sua configuração deve ser preservada.Se eu tentar fazer uma alteração simples na tabela usando o designer de tabelas SSMS, como adicionar uma nova coluna, o SSMS gerará um script que não recriará a tabela:
Como você pode ver, ele ainda adiciona a
ALTER TABLE SET LOCK_ESCALATION
declaração, embora neste caso não seja necessária. O primeiroALTER TABLE ... ADD
não altera a configuração atual. Acho que os desenvolvedores do SSMS decidiram que não vale a pena tentar determinar em que casos essaALTER TABLE SET LOCK_ESCALATION
declaração é redundante e gerá-la sempre, apenas para garantir a segurança. Não há mal nenhum em adicionar esta declaração sempre.Mais uma vez, a
LOCK_ESCALATION
configuração de toda a tabela é irrelevante enquanto o esquema da tabela é alterado por meio daALTER TABLE
instruçãoLOCK_ESCALATION
A configuração afeta apenas o comportamento de bloqueio das instruções DML, comoUPDATE
.Finalmente, uma citação de
ALTER TABLE
, enfatize a minha:fonte