Usamos updlock em algumas instruções select para garantir que apenas uma conexão possa ler os dados. Isso não parece funcionar se o SQL Server puder buscar todos os dados de um índice, quando a outra consulta que também emite um updlock pode ser satisfeita com outro índice (não)clusterizado.
Qual seria a abordagem recomendada para ter bloqueios que realmente bloqueiem um registro de tabela, mesmo que outras consultas possam ser satisfeitas com dados de um índice?
Exemplo, conn2 deve ser bloqueado até que conn1 seja confirmado/revertido:
create database TestDB
go
use TestDB
go
create table LockTest(
LockTestID int not null identity(1,1) primary key,
Number int
)
create index IX_LockTest on LockTest(Number)
insert into LockTest(Number) values(1)
--Conn1
begin tran
select LockTestID from LockTest with(updlock) where LockTestID=1
--Conn2 -- The expectation here is, that this query waits untill Conn1 has committed
begin tran
select LockTestID from LockTest with(updlock) where Number=1
Mesmos resultados com holdlock ou lock
Correto, isso está documentado:
https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16#remarks
Então, se você quiser usar dicas de bloqueio para serializar essas duas transações, você também precisará de uma dica de índice, para que elas bloqueiem o mesmo índice.
Pode ser, embora a coluna extra torne isso menos provável. A única maneira de ter certeza é usar a dica de índice também.
Se você precisar de mais controle do que o fornecido pela sintaxe e pelos recursos básicos, talvez seja necessário um bloqueio de aplicativo .