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
2番目のセッションは、最初のセッションが完了するのを待ってから続行します。
WITH (READPAST)
他のセッションによってロックされている行をスキップするようにSQL Serverに指示します。本当によろしいですか?また、このテーブルの何行を変更していますか?テーブルスキーマ(インデックスを含む)とMERGE
実行しているステートメントを表示します。