Eu tenho um procedimento armazenado que executa uma MERGE
instrução .
Parece que bloqueia a tabela inteira por padrão ao executar a mesclagem.
Estou chamando esse procedimento armazenado dentro de uma transação em que também estou fazendo outras coisas e gostaria que ele apenas bloqueasse as linhas afetadas.
Eu tentei a dica MERGE INTO myTable WITH (READPAST)
e parecia travar menos. Mas havia um aviso no ms doc que dizia que ele poderia inserir chaves duplicadas, ignorando até a chave primária.
Aqui está o meu esquema de tabela:
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
Aqui está o meu procedimento armazenado:
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
Aqui está como eu estou observando o bloqueio:
begin tran
EXEC MergeTest 1, 1
E então em outra sessão:
EXEC MergeTest 2, 2
A segunda sessão aguarda a conclusão da primeira antes de continuar.
WITH (READPAST)
instrui o SQL Server a ignorar apenas as linhas bloqueadas por outras sessões. Você tem certeza que deseja fazer isso? Além disso, quantas linhas nesta tabela você está modificando? Mostre-nos o esquema da tabela (incluindo índices) e aMERGE
instrução que você está executando.