У мене зберігається процедура, яка виконує 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
Другий сеанс чекає завершення першого, перш ніж продовжити.
WITH (READPAST)
вказує SQL Server просто пропускати рядки, які заблоковані іншими сесіями. Ви впевнені, що хочете це зробити? Крім того, скільки рядків у цій таблиці ви змінюєте? Покажіть нам схему таблиці (включаючи індекси) таMERGE
оператор, який ви запускаєте.