Ao pesquisar o uso de dicas de tabela , me deparei com estas duas perguntas:
As respostas a ambas as perguntas dizem que, ao usar (UPDLOCK, HOLDLOCK)
, outros processos não serão capazes de ler os dados daquela tabela, mas eu não vi isso. Para testar, criei uma tabela e iniciei duas janelas SSMS. Na primeira janela, executei uma transação que selecionei na tabela usando várias dicas de tabela. Enquanto a transação estava sendo executada, na segunda janela, executei várias instruções para ver quais seriam bloqueadas.
A mesa de teste:
CREATE TABLE [dbo].[Test](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Value] [nvarchar](50) NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Da janela 1 do SSMS:
BEGIN TRANSACTION
SELECT * FROM dbo.Test WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:10'
COMMIT TRANSACTION
Na janela 2 do SSMS (executou um dos seguintes):
SELECT * FROM dbo.Test
INSERT dbo.Test(Value) VALUES ('bar')
UPDATE dbo.Test SET Value = 'baz' WHERE Value = 'bar'
DELETE dbo.Test WHERE Value= 'baz'
Efeito de diferentes dicas de tabela nas instruções executadas na janela 2:
(UPDLOCK) (HOLDLOCK) (UPDLOCK, HOLDLOCK) (TABLOCKX)
---------------------------------------------------------------------------
SELECT not blocked not blocked not blocked blocked
INSERT not blocked blocked blocked blocked
UPDATE blocked blocked blocked blocked
DELETE blocked blocked blocked blocked
Eu entendi mal as respostas dadas nessas perguntas ou cometi um erro em meus testes? Se não, por que você usaria (UPDLOCK, HOLDLOCK)
vs. (HOLDLOCK)
sozinho?
Mais explicações sobre o que estou tentando realizar:
Gostaria de selecionar linhas de uma tabela e evitar que os dados dessa tabela sejam modificados enquanto estou processando-os. Não estou modificando esses dados e gostaria de permitir que ocorram leituras.
Esta resposta diz claramente que (UPDLOCK, HOLDLOCK)
bloqueará leituras (não o que eu quero). Os comentários a esta resposta implicam que é isso HOLDLOCK
que impede leituras. Para tentar entender melhor os efeitos das dicas de tabela e ver se UPDLOCK
sozinho faria o que eu queria, fiz o experimento acima e obtive resultados que contradizem essas respostas.
Atualmente, acredito que (HOLDLOCK)
seja isso que devo usar, mas estou preocupado que possa ter cometido um erro ou esquecido algo que voltará a me morder no futuro, daí esta questão.
fonte
UPDLOCK é usado quando você deseja bloquear uma linha ou linhas durante uma instrução de seleção para uma instrução de atualização futura. A atualização futura pode ser a próxima instrução da transação.
Outras sessões ainda podem ver os dados. Eles simplesmente não podem obter bloqueios incompatíveis com o UPDLOCK e / ou HOLDLOCK.
Você usa UPDLOCK quando deseja impedir que outras sessões alterem as linhas que você bloqueou. Isso restringe sua capacidade de atualizar ou excluir linhas bloqueadas.
Use HOLDLOCK quando quiser evitar que outras sessões alterem qualquer um dos dados que você está olhando. Isso restringe a capacidade de inserir, atualizar ou excluir as linhas que você bloqueou. Isso permite que você execute a consulta novamente e veja os mesmos resultados.
fonte
(UPDLOCK,HOLDLOCK)
bloco era lido e há uma razão para usar em(UPDLOCK,HOLDLOCK)
vez de apenas(HOLDLOCK)
?