关于锁定表格,这两个语句有何不同之处:
-- 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,但是对于Variation 2,当多个会话同时执行此代码时,我会遇到死锁。对于变体1,我没有。我认为这两种方法的工作方式相同,但显然锁定TABLOCKX的方式或保持时间有所不同。
有些知识渊博的人请对此有所了解。