Compartilhar via


Bloqueio otimizado

Aplica-se a: SQL Server 2025 (17.x) Banco de Dados SQL do AzureInstância Gerenciada de SQL do Azurebanco de dados SQL no Microsoft Fabric

O bloqueio otimizado oferece um mecanismo aprimorado de bloqueio de transações para reduzir o bloqueio de travas e o consumo de memória de travas em transações simultâneas.

O que é bloqueio otimizado?

O bloqueio otimizado ajuda a reduzir a memória de bloqueio, uma vez que são retidos poucos bloqueios mesmo para grandes transações. Além disso, o bloqueio otimizado evita escalonamentos de bloqueio e pode evitar certos tipos de deadlocks. Isso permite maior acesso simultâneo à tabela.

O bloqueio otimizado tem dois componentes principais: bloqueio de ID da transação (TID) e bloqueio após qualificação (LAQ).

  • A TID (ID da transação) é um identificador exclusivo da transação. Cada linha é rotulada com a última TID que a modificou. Em vez de potencialmente muitos bloqueios de identificador de linha ou chave, utiliza-se um único bloqueio no TID para salvaguardar todas as linhas modificadas. Para obter mais informações, consulte Bloqueio de ID de transação (TID).
  • O bloqueio após qualificação (LAQ) é uma otimização que avalia predicados de consulta usando a versão mais recente confirmada da linha sem adquirir um bloqueio, melhorando assim a simultaneidade. O LAQ requer RCSI (isolamento de instantâneo confirmado por leitura). Para obter mais informações, consulte Bloqueio após qualificação (LAQ).

Por exemplo:

  • Sem bloqueio otimizado, a atualização de mil linhas em uma tabela pode exigir mil bloqueios de linha exclusivos (X) mantidos até o final da transação.
  • Com o bloqueio otimizado, a atualização de 1.000 linhas em uma tabela pode exigir 1.000 X bloqueios de linha, mas cada bloqueio é liberado assim que cada linha é atualizada e apenas um X bloqueio TID é mantido até o final da transação. Como os bloqueios são liberados rapidamente, o uso da memória de bloqueio é reduzido e o escalonamento de bloqueios é muito menos provável de ocorrer, melhorando a simultaneidade da carga de trabalho.

Note

Habilitar o bloqueio otimizado reduz ou elimina bloqueios de linha e de página adquiridos pelas instruções DML (linguagem de manipulação de dados), como INSERT, UPDATE, DELETE, MERGE. Ele não tem efeito em outros tipos de bloqueios de banco de dados e objeto, como bloqueios de esquema.

Availability

A tabela a seguir resume a disponibilidade e o estado habilitado do bloqueio otimizado em plataformas SQL.

Platform Available Habilitado por padrão
Banco de Dados SQL do Azure Yes Sim (sempre habilitado)
Banco de dados SQL no Microsoft Fabric Yes Sim (sempre habilitado)
Instância Gerenciada de SQL do AzureAUTD Yes Sim (sempre habilitado)
Instância Gerenciada de SQL do Azure2025 Yes Sim (sempre habilitado)
Instância Gerenciada de SQL do Azure2022 No N/A
SQL Server 2025 (17.x) Yes Não (pode ser habilitado por banco de dados)
SQL Server 2022 (16.x) e versões mais antigas No N/A

Habilitar e desabilitar

Para habilitar ou desabilitar o bloqueio otimizado para um banco de dados do SQL Server, use o ALTER DATABASE ... SET OPTIMIZED_LOCKING = ON | OFF comando. Para obter mais informações, consulte Opções ALTER DATABASE SET.

O bloqueio otimizado se baseia em outros recursos de banco de dados:

A ADR está sempre habilitada no Banco de Dados SQL do Azure, na Instância Gerenciada de SQL do Azure e no Banco de Dados SQL no Microsoft Fabric. O RCSI é habilitado por padrão no Banco de Dados SQL do Azure e no Banco de Dados SQL no Microsoft Fabric.

Para verificar se essas opções estão habilitadas no banco de dados atual, conecte-se ao banco de dados e execute a seguinte consulta T-SQL:

SELECT database_id,
       name,
       is_accelerated_database_recovery_on,
       is_read_committed_snapshot_on,
       is_optimized_locking_on
FROM sys.databases
WHERE name = DB_NAME();

O bloqueio otimizado está habilitado?

O bloqueio otimizado é habilitado por banco de dados. Conecte-se ao banco de dados e use a seguinte consulta para verificar se o bloqueio otimizado está habilitado:

SELECT DATABASEPROPERTYEX(DB_NAME(), 'IsOptimizedLockingOn') AS is_optimized_locking_enabled;
Result Description
0 O bloqueio otimizado está desabilitado.
1 O bloqueio otimizado está habilitado.
NULL O bloqueio otimizado não está disponível.

Você também pode usar a exibição de catálogo sys.databases . Por exemplo, para ver se o bloqueio otimizado está habilitado para todos os bancos de dados, execute a seguinte consulta:

SELECT database_id,
       name,
       is_optimized_locking_on
FROM sys.databases;

Visão geral do bloqueio

Esse é um breve resumo do comportamento quando o bloqueio otimizado não está habilitado. Para obter mais informações, leia o Guia de controle de versão de linha e bloqueio de transações.

No mecanismo de banco de dados, o bloqueio é um mecanismo que impede que várias transações atualizem os mesmos dados ao mesmo tempo para garantir as propriedades ACID das transações.

Quando precisa modificar dados, uma transação solicita um bloqueio dos dados. O bloqueio é concedido se nenhum outro bloqueio conflitante estiver retido nos dados, e a transação pode prosseguir com a modificação. Se outro bloqueio conflitante estiver retido nos dados, a transação deverá aguardar que o bloqueio seja liberado antes de prosseguir.

Quando várias transações tentam acessar os mesmos dados ao mesmo tempo, o mecanismo de banco de dados deve resolver conflitos potencialmente complexos com leituras e gravações simultâneas. O bloqueio é um dos instrumentos pelos quais o mecanismo pode fornecer a semântica para os níveis de isolamento da transação ANSI SQL. Embora o bloqueio em bancos de dados seja essencial, a redução da simultaneidade, dos deadlocks, da complexidade e da sobrecarga de bloqueio pode afetar o desempenho e a escalabilidade.

Bloqueio de ID de Transação (TID)

Quando o controle de versão de linha baseado em níveis de isolamento está em uso, ou quando o ADR está habilitado, cada linha do banco de dados contém internamente uma ID de transação (TID). TID é persistida com a linha. Cada transação que modifica uma linha marca a linha com seu TID.

Com o bloqueio de TID, em vez de tirar o bloqueio da chave da linha, retira-se o bloqueio da TID da linha. A transação de modificação mantém um bloqueio X na TID. Outras transações adquirem um bloqueio S na TID para aguardar até que a primeira transação seja concluída. Com o bloqueio de TID, os bloqueios de página e de linha continuam em uso para modificações, mas cada bloqueio de página e de linha é liberado assim que cada linha é modificada. O único bloqueio mantido até o final da transação é o bloqueio X único no recurso TID, substituindo vários bloqueios de página e de linha (chave).

Considere o exemplo a seguir, que mostra bloqueios para a sessão atual enquanto uma transação de gravação está ativa:

/* Is optimized locking is enabled? */
SELECT DATABASEPROPERTYEX(DB_NAME(), 'IsOptimizedLockingOn') AS is_optimized_locking_enabled;

CREATE TABLE t0
(
a int PRIMARY KEY,
b int NULL
);

INSERT INTO t0 VALUES (1,10),(2,20),(3,30);
GO

BEGIN TRANSACTION;

UPDATE t0
SET b = b + 10;

SELECT *
FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID
      AND
      resource_type IN ('PAGE','RID','KEY','XACT');

COMMIT TRANSACTION;
GO

DROP TABLE IF EXISTS t0;

Se o bloqueio otimizado está habilitado, a solicitação mantém apenas um bloqueio X único no recurso XACT (transação).

A captura de tela do conjunto de resultados de uma consulta em sys.dm_tran_locks para uma única sessão mostra apenas um bloqueio quando o bloqueio otimizado está habilitado.

Caso o bloqueio otimizado não esteja habilitado, a mesma solicitação possui quatro bloqueios: um bloqueio IX (intenção exclusiva) na página que contém as linhas e três bloqueios de chave X em cada linha.

Captura de tela do conjunto de resultados de uma consulta em sys.dm_tran_locks para uma só sessão mostra três bloqueios quando o bloqueio otimizado não está habilitado.

O sys.dm_tran_locks DMV (modo de exibição de gerenciamento dinâmico) é útil para examinar ou solucionar problemas de bloqueio. Aqui é usado para observar o bloqueio otimizado em operação.

Bloqueio após qualificação (LAQ)

Com base na infraestrutura TID, o componente LAQ do bloqueio otimizado altera a forma como as instruções DML, como INSERT, UPDATEe DELETE adquirem bloqueios.

Sem o bloqueio otimizado, os predicados de consulta são verificados linha por linha em uma verificação fazendo primeiro um bloqueio de linha de atualização (U). Se o predicado foi atendido, é feito um bloqueio de linha exclusivo (X) antes de atualizar a linha e mantido até o fim da transação.

Com o bloqueio otimizado e quando o nível de isolamento do READ COMMITTED instantâneo (RCSI) está habilitado, os predicados podem ser verificados com otimismo na versão confirmada mais recente da linha sem realizar bloqueios. Se o predicado não é atendido, a consulta muda para a próxima linha da verificação. Se o predicado é atendido, é feito um bloqueio de linha X para atualizar a linha.

Em outras palavras, o bloqueio é feito após a qualificação da linha para modificação. O bloqueio de linha X é liberado assim que a atualização de linha é concluída, antes do fim da transação.

Como a avaliação de predicados é feita sem adquirir bloqueios, consultas simultâneas que modificam linhas diferentes não bloqueiam umas às outras.

Por exemplo:

/* Confirm that optimized locking and read committed snapshot isolation (RCSI) are both enabled on this database. */
SELECT database_id,
       name,
       is_accelerated_database_recovery_on,
       is_optimized_locking_on,
       is_read_committed_snapshot_on
FROM sys.databases
WHERE name = DB_NAME();

CREATE TABLE t1
(
a int NOT NULL,
b int NULL
);

INSERT INTO t1
VALUES (1,10),(2,20),(3,30);
GO
Sessão 1 Sessão 2
BEGIN TRANSACTION;
UPDATE t1
SET b = b + 10
WHERE a = 1;
BEGIN TRANSACTION;
UPDATE t1
SET b = b + 10
WHERE a = 2;
COMMIT TRANSACTION;
COMMIT TRANSACTION;

Sem o bloqueio otimizado, a sessão 2 é bloqueada porque a sessão 1 mantém um bloqueio U na linha que a sessão 2 precisa ser atualizada. Porém, com o bloqueio otimizado, a sessão 2 não é bloqueada devido à ausência de bloqueios U e porque a coluna a é igual a 1 na última versão confirmada da linha 1, o que não atende o predicado da sessão 2.

O LAQ é executado com otimismo supondo que uma linha não é modificada após a verificação do predicado. Se o predicado for atendido e a linha não tiver sido modificada após a verificação do predicado, ela é modificada pela transação atual.

Como os U bloqueios não são feitos, uma transação simultânea pode modificar a linha após a avaliação do predicado. Se houver uma transação ativa mantendo um X bloqueio TID na linha, o mecanismo de banco de dados aguarda a sua conclusão. Se a linha tiver sido alterada após o predicado ter sido avaliado anteriormente, o mecanismo de banco de dados reavaliará (requalifica) o predicado novamente antes de modificar a linha. Se o predicado ainda for atendido, a linha será modificada.

A requalificação do predicado é suportada por um subconjunto dos operadores do mecanismo de consulta. Se a reavaliação do predicado for necessária, mas o plano de consulta utilizar um operador que não dê suporte à requalificação do predicado, o mecanismo de banco de dados interromperá internamente o processamento da instrução e o reiniciará sem LAQ. Quando essa anulação ocorre, é disparado o evento estendido lock_after_qual_stmt_abort.

Algumas instruções, por exemplo UPDATE , com atribuição de variável e instruções com a cláusula OUTPUT , não podem ser anuladas e reiniciadas sem alterar a semântica. Para essas declarações, LAQ não é utilizado.

No exemplo a seguir, o predicado é reavaliado porque outra transação alterou a linha:

CREATE TABLE t3
(
a int NOT NULL,
b int NULL
);

INSERT INTO t3 VALUES (1,10),(2,20),(3,30);
GO
Sessão 1 Sessão 2
BEGIN TRANSACTION;
UPDATE t3
SET b = b + 10
WHERE a = 1;
BEGIN TRANSACTION;
UPDATE t3
SET b = b + 10
WHERE a = 1;
COMMIT TRANSACTION;
COMMIT TRANSACTION;

Ignorar bloqueios de índice (SIL)

Com o bloqueio de TID, são usados bloqueios de linha exclusivos de curta duração (X) e bloqueios de página de intenção exclusiva (IX) para modificar linhas. Quando RCSI e LAQ são usados, esses bloqueios só são necessários se houver outras consultas acessando a linha e esperando que ela seja estável. Exemplos dessas consultas são aquelas em execução sob os níveis de isolamento REPEATABLE READ ou SERIALIZABLE, ou usando as dicas de bloqueio correspondentes. Essas consultas são conhecidas como RLQ ( consultas de bloqueio de linha ).

Quando não há consultas RLQ acessando uma linha, o mecanismo de banco de dados pode ignorar a tomada de bloqueios de linha e página ao modificar uma linha e usar apenas uma trava de página exclusiva. Essa otimização reduz a sobrecarga de bloqueio ao preservar a semântica de transação ACID. Ignorar bloqueios de linha e página beneficia especialmente as transações que modificam um grande número de linhas.

Atualmente, a otimização do SIL é usada somente nos seguintes casos:

  • INSERT instruções em heaps.
    • IX bloqueios de página são ignorados.
  • UPDATE instruções sobre índices clusterizados, índices não clusterizados e heaps.
    • IX bloqueios de página e X bloqueios de linha são ignorados.

Atualmente, a otimização do SIL não é usada nos seguintes casos:

  • InstruçõesDELETE .
  • UPDATE instruções em heaps se a linha contiver ponteiros de encaminhamento existentes ou se novos ponteiros de encaminhamento forem adicionados pela atualização.
  • Se a linha modificada tiver colunas usando os tipos de dados LOB, como varchar(max), nvarchar(max), varbinary(max) e json.
  • Para linhas em páginas que foram divididas na mesma transação.

Heurísticas LAQ

Conforme descrito no LAQ (Lock after qualification), quando o LAQ é usado, instruções que usam operadores de consulta que não dão suporte à requalificação de predicado podem ser reiniciadas internamente e processadas sem LAQ. Se isso acontecer com frequência, a sobrecarga de reprocessamento poderá se tornar significativa. Para minimizar a sobrecarga, o bloqueio otimizado usa um mecanismo de feedback baseado em técnicas heurísticas que desabilita o LAQ se a sobrecarga exceder os limites.

Para os fins do mecanismo de feedback, o trabalho realizado por uma instrução é medido pelo número de leituras lógicas. Se o mecanismo de banco de dados estiver modificando uma linha que foi modificada por outra transação após o início do processamento da instrução, o trabalho feito pela instrução será tratado como potencialmente desperdiçado porque a instrução pode precisar ser reprocessada.

À medida que as instruções são executadas, o mecanismo de banco de dados mantém dados de feedback LAQ que rastreiam o potencial de trabalho desperdiçado, as ocorrências de reprocessamento de instruções e o trabalho total feito pelas instruções que podem ser reprocessadas.

O LAQ será desabilitado se a proporção do trabalho potencialmente desperdiçado para o trabalho total ou a proporção do número de instruções reprocessadas para o número total de instruções exceder seus respectivos limites. Caso ambas as proporções estejam abaixo dos limites, o LAQ será reativado.

Os dados de comentários do LAQ são acompanhados em dois níveis:

  • Para um plano de consulta.

    • O mecanismo de banco de dados começa a acompanhar os comentários do LAQ para um plano sobre a primeira ocorrência de reprocessamento de instrução.
    • Se uma consulta for capturada no Repositório de Consultas, os comentários do LAQ também serão capturados no Repositório de Consultas. O mecanismo de banco de dados usa esses comentários para manter o LAQ habilitado ou desabilitado para o plano se o banco de dados for reiniciado.
    • Os planos de consulta com comentários LAQ capturados têm uma linha com um valor correspondente plan_id na exibição de catálogo sys.query_store_plan_feedback. As feature_id colunas e as colunas feature_desc são definidas como 4 e LAQ Feedback respectivamente.
  • Para um banco de dados.

    • Os feedbacks são agregados para todas as instruções que não têm feedback no nível do plano de consulta; por exemplo, se uma consulta não for capturada no Repositório de Consultas.
    • Os comentários são acompanhados desde a inicialização do banco de dados e recriados após cada inicialização.

Quando se decide usar o LAQ para uma instrução, o sistema utiliza o feedback do plano de consulta, se este estiver disponível. Caso contrário, ele utilizará o feedback no nível do banco de dados. Isso significa que algumas instruções podem ser executadas com LAQ e algumas podem ser executadas sem LAQ. Por exemplo, o LAQ pode estar desabilitado para um plano de consulta, mas habilitado para o banco de dados e vice-versa.

Limitações do LAQ

O bloqueio após a qualificação não é usado nos seguintes cenários:

  • Quando desabilitado pela heurística do LAQ.
  • Quando dicas de bloqueio conflitantes, como UPDLOCK, READCOMMITTEDLOCK, XLOCK ou HOLDLOCK são usadas.
  • Quando o nível de isolamento da transação é diferente READ COMMITTEDou quando a opção READ_COMMITTED_SNAPSHOT de banco de dados está desabilitada.
  • Quando a tabela que está sendo modificada tem um índice columnstore.
  • Quando a instrução DML inclui atribuição de variável.
  • Quando a instrução DML tem uma cláusula OUTPUT.
  • Quando a instrução DML usa mais de um operador de busca ou verificação de índice para ler as linhas que estão sendo modificadas.
  • Em instruções MERGE.

Alterações no comportamento da consulta com bloqueio otimizado e RCSI

Cargas de trabalho simultâneas no isolamento de instantâneo confirmado por leitura (RCSI) que dependem de ordem de execução estrita de transações podem apresentar diferenças no comportamento de consulta quando o bloqueio otimizado está habilitado.

Veja o exemplo a seguir, em que a transação T2 está atualizando a tabela t4 com base na coluna b que foi atualizada durante a transação T1.

CREATE TABLE t4
(
a int NOT NULL,
b int NULL
);

INSERT INTO t4
VALUES (1,1);
GO
Sessão 1 Sessão 2
BEGIN TRANSACTION T1;
UPDATE t4
SET b = 2
WHERE a = 1;
BEGIN TRANSACTION T2;
UPDATE t4
SET b = 3
WHERE b = 2;
COMMIT TRANSACTION;
COMMIT TRANSACTION;

Vamos avaliar o resultado do cenário anterior com e sem bloqueio após qualificação (LAQ).

Sem LAQ

Sem LAQ, a instrução UPDATE na transação T2 é bloqueada, aguardando a transação T1 ser concluída. Depois que T1 é concluída, T2 atualiza a coluna de configuração de linha b para 3 porque o predicado foi atendido.

Após a confirmação das duas transações, a tabela t4 contém as seguintes linhas:

 a | b
 1 | 3

Com LAQ

Com LAQ, a transação T2 usa a versão confirmada mais recente da linha em que a coluna b é igual a 1 para avaliar o predicado (b = 2). A linha não se qualifica; portanto, ela é ignorada e a instrução é concluída sem ter sido bloqueada pela transação T1. Neste exemplo, o LAQ remove o bloqueio, mas gera resultados diferentes.

Após a confirmação das duas transações, a tabela t4 contém as seguintes linhas:

 a | b
 1 | 2

Important

Mesmo sem LAQ, os aplicativos não devem assumir que o mecanismo de banco de dados garante uma ordenação estrita sem usar dicas de bloqueio quando os níveis de isolamento baseados em controle de versão de linha são usados. Nossa recomendação geral para clientes que executam cargas de trabalho de transações simultâneas no RCSI que dependem de ordem de execução estrita de transações (como visto no exemplo anterior) é usar níveis de isolamento mais rigorosos, como REPEATABLE READ e SERIALIZABLE.

Adições de diagnóstico para bloqueio otimizado

Os seguintes aprimoramentos ajudam a monitorar e solucionar problemas de bloqueio e deadlocks quando o bloqueio otimizado está habilitado:

  • Tipos de espera para bloqueio otimizado
    • XACT tipos de espera para o S bloqueio no TID e descrições de recursos no sys.dm_os_wait_stats:
      • LCK_M_S_XACT_READ: ocorre quando uma tarefa está aguardando um bloqueio compartilhado em um tipo XACTwait_resource, com uma intenção de ler.
      • LCK_M_S_XACT_MODIFY: ocorre quando uma tarefa está aguardando um bloqueio compartilhado em um tipo XACTwait_resource, com uma intenção de modificar.
      • LCK_M_S_XACT: ocorre quando uma tarefa está aguardando um bloqueio compartilhado em um tipo XACTwait_resource, em que a intenção não pode ser inferida. Esse cenário não é comum.
  • Bloqueando a visibilidade dos recursos
    • XACT bloqueando recursos. Para obter mais informações, consulte resource_descriptionsys.dm_tran_locks.
  • Aguardar visibilidade dos recursos
    • XACT aguardar recursos. Para obter mais informações, consulte wait_resourcesys.dm_exec_requests.
  • Grafo de bloqueio
    • Em cada recurso no relatório de deadlock <resource-list>, cada elemento <xactlock> relata os recursos subjacentes e as informações específicas para bloqueios de cada membro de um deadlock. Para obter mais informações e um exemplo, consulte Bloqueio otimizado e deadlocks.
  • Eventos estendidos
    • O evento lock_after_qual_stmt_abort é acionado quando uma instrução é reprocessada internamente por causa de um conflito com outra transação. Para obter mais informações, consulte Bloqueio após qualificação (LAQ).
    • O evento locking_stats é acionado para cada banco de dados a cada poucos minutos e fornece estatísticas agregadas de bloqueio para o intervalo de tempo, como o número de escalonamentos de bloqueio, se o bloqueio de TID e os componentes LAQ do bloqueio otimizado estão habilitados e o número de consultas nas quais o LAQ não foi utilizado por vários motivos. Esse evento é acionado mesmo se o bloqueio otimizado está desabilitado.
    • No SQL Server e na Instância Gerenciada de SQL do Azure, o locking_stats2 evento é acionado para cada banco de dados a cada vários minutos e fornece os bloqueios de índice skip e as estatísticas de heurística do LAQ para o intervalo de tempo.

Práticas recomendadas com bloqueio otimizado

Habilitar isolamento de instantâneo confirmado por leitura (RCSI)

Para maximizar os benefícios do bloqueio otimizado, é recomendável habilitar o RCSI (isolamento de instantâneo confirmado por leitura) no banco de dados e usar READ COMMITTED o isolamento como o nível de isolamento padrão.

No Banco de Dados SQL do Azure e no Banco de Dados SQL no Microsoft Fabric, o RCSI é habilitado por padrão e READ COMMITTED é o nível de isolamento padrão. Com o RCSI habilitado e ao usar o nível de isolamento READ COMMITTED, os leitores leem uma versão da linha do instantâneo tirado no início da instrução. Com LAQ, os gravadores qualificam as linhas de acordo com o predicado, com base na versão confirmada mais recente da linha e sem adquirir bloqueios U. Com LAQ, a consulta aguarda somente se a linha se qualifica e se há uma transação de gravação ativa nessa linha. Qualificar com base na versão confirmada mais recente e bloquear apenas as linhas qualificadas reduz o bloqueio e aumenta a simultaneidade.

Dicas para evitar bloqueio

Embora as dicas de tabela e consulta, como UPDLOCK, READCOMMITTEDLOCK, XLOCK, HOLDLOCK etc., sejam respeitadas quando o bloqueio otimizado está habilitado, elas reduzem o benefício do bloqueio otimizado. As sugestões de bloqueio forçam o mecanismo de banco de dados a utilizar bloqueios de linha ou de página e a mantê-los até o final da transação, para cumprir o propósito das sugestões de bloqueio. Alguns aplicativos têm uma lógica em que as dicas de bloqueio são necessárias, por exemplo, ao ler uma linha com a dica UPDLOCK e atualizá-la depois. Recomendamos usar dicas de bloqueio apenas quando for necessário.

Com o bloqueio otimizado, não há restrições em consultas existentes e as consultas não precisam ser reescritas. As consultas que não usam dicas se beneficiam mais do bloqueio otimizado.

Uma dica de tabela em uma tabela de uma consulta não desabilita o bloqueio otimizado em outras tabelas da mesma consulta. Além disso, o bloqueio otimizado afeta somente o comportamento de bloqueio das tabelas que estão sendo atualizadas por uma instrução DML, como INSERT, UPDATE, DELETE ou MERGE. Por exemplo:

CREATE TABLE t5
(
a int NOT NULL,
b int NOT NULL
);

CREATE TABLE t6
(
a int NOT NULL,
b int NOT NULL
);
GO

INSERT INTO t5 VALUES (1,10),(2,20),(3,30);
INSERT INTO t6 VALUES (1,10),(2,20),(3,30);
GO

UPDATE t5 SET t5.b = t6.b
FROM t5
INNER JOIN t6 WITH (UPDLOCK)
ON t5.a = t6.a;

No exemplo de consulta anterior, apenas a tabela t6 é afetada pela dica de bloqueio, enquanto t5 ainda pode se beneficiar do bloqueio otimizado.

UPDATE t5
    SET t5.b = t6.b
FROM t5 WITH (REPEATABLEREAD)
     INNER JOIN t6
         ON t5.a = t6.a;

No exemplo de consulta anterior, somente a tabela t5 usa o nível de isolamento REPEATABLE READ e mantém bloqueios até o fim da transação. Outras atualizações para t5 ainda podem se beneficiar do bloqueio otimizado. O mesmo se aplica à dica HOLDLOCK.

Perguntas frequentes (FAQ)

O bloqueio otimizado é ativado por padrão em bancos de dados novos e já existentes?

No Banco de Dados SQL do Azure, na Instância Gerenciada AUTD de SQL do Azure e no Banco de Dados SQL no Microsoft Fabric, sim. No SQL Server 2025 (17.x), o bloqueio otimizado é desabilitado por padrão, mas pode ser habilitado em qualquer banco de dados de usuário que tenha a recuperação acelerada do banco de dados habilitada.

Como detectar se o bloqueio otimizado está habilitado?

Veja Se o bloqueio otimizado está habilitado?

E se eu quiser forçar o bloqueio de consultas mesmo com o bloqueio otimizado?

Se o RCSI está habilitado, use a dica de tabela READCOMMITTEDLOCK para forçar o bloqueio entre duas consultas quando o bloqueio otimizado está habilitado.

O bloqueio otimizado é usado em réplicas secundárias somente leitura?

Não, pois as instruções DML não podem ser executadas em réplicas somente leitura, e os bloqueios de linha e de página correspondentes não são feitos.

O bloqueio otimizado é usado ao modificar dados em tempdb e em tabelas temporárias?

Não no momento.