Чем эти два утверждения отличаются в отношении блокировки таблицы:
-- Variation 1
BEGIN TRAN
-- Lock the table explicitly via a SELECT
DECLARE @TempId BIGINT=(SELECT TOP(1) Id FROM TargetTable WITH (TABLOCKX, HOLDLOCK));
-- Then perform DML operations
MERGE TargetTable as target
USING (...) AS source
ON (target.Id=source.Id)
WHEN MATCHED THEN
DELETE
WHEN NOT MATCHED THEN
INSERT ... ;
DELETE FROM Target
WHERE Id=...
COMMIT TRAN
По сравнению с:
-- Variation 2
BEGIN TRAN
-- Lock the table as part of the first DML operation
MERGE TargetTable WITH (TABLOCKX, HOLDLOCK) as target
USING (...) AS source
ON (target.Id=source.Id)
WHEN MATCHED THEN
DELETE
WHEN NOT MATCHED THEN
INSERT ... ;
DELETE FROM Target
WHERE Id=...
COMMIT TRAN
В одной и той же таблице TABLOCKX помещается в обоих случаях, но с Вариантом 2 я получаю тупик, когда несколько сессий одновременно выполняют этот код. С Вариацией 1 у меня нет. Я думал, что они будут работать одинаково, но, видимо, есть некоторая разница в том, как получить блокировку TABLOCKX или как долго она удерживается.
Не мог бы какой-нибудь знающий человек пролить свет на это.