我有一个执行MERGE
语句的存储过程。
似乎在执行合并时默认情况下会锁定整个表。
我正在事务内调用此存储过程,在该事务中我还在做其他一些事情,但愿它只会锁定受影响的行。
我尝试了提示MERGE INTO myTable WITH (READPAST)
,但似乎锁得少了。但是ms doc中有一个警告,说它可以插入重复的键,甚至绕过主键。
这是我的表架构:
CREATE TABLE StudentDetails
(
StudentID INTEGER PRIMARY KEY,
StudentName VARCHAR(15)
)
GO
INSERT INTO StudentDetails
VALUES(1,'WANG')
INSERT INTO StudentDetails
VALUES(2,'JOHNSON')
GO
CREATE TABLE StudentTotalMarks
(
Id INT IDENTITY PRIMARY KEY,
StudentID INTEGER REFERENCES StudentDetails,
StudentMarks INTEGER
)
GO
INSERT INTO StudentTotalMarks
VALUES(1,230)
INSERT INTO StudentTotalMarks
VALUES(2,255)
GO
这是我的存储过程:
CREATE PROCEDURE MergeTest
@StudentId int,
@Mark int
AS
WITH Params
AS
(
SELECT @StudentId as StudentId,
@Mark as Mark
)
MERGE StudentTotalMarks AS stm
USING Params p
ON stm.StudentID = p.StudentId
WHEN MATCHED AND stm.StudentMarks > 250 THEN DELETE
WHEN MATCHED THEN UPDATE SET stm.StudentMarks = p.Mark
WHEN NOT MATCHED THEN
INSERT(StudentID,StudentMarks)
VALUES(p.StudentId, p.Mark);
GO
这是我观察锁定的方式:
begin tran
EXEC MergeTest 1, 1
然后在另一个会话中:
EXEC MergeTest 2, 2
在继续之前,第二个会话等待第一个会话完成。
@NickChammas谢谢您的帮助,我用详细信息更新了问题。我想READPAST会不好...
—
John Buchanan 2012年
WITH (READPAST)
指示SQL Server仅跳过其他会话锁定的行。您确定要这样做吗?另外,您要修改此表中的几行?向我们显示表模式(包括索引)和MERGE
您正在运行的语句。