Tengo un procedimiento almacenado que realiza una MERGE
declaración .
Parece que bloquea toda la tabla de forma predeterminada al realizar la fusión.
Llamo a este procedimiento almacenado dentro de una transacción donde también estoy haciendo otras cosas y deseo que solo bloquee las filas afectadas.
Probé la pista MERGE INTO myTable WITH (READPAST)
y pareció bloquearse menos. Pero había una advertencia en el documento de ms que decía que podía insertar claves duplicadas, omitiendo incluso la clave primaria.
Aquí está mi esquema de tabla:
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
Aquí está mi procedimiento almacenado:
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
Así es como estoy observando el bloqueo:
begin tran
EXEC MergeTest 1, 1
Y luego en otra sesión:
EXEC MergeTest 2, 2
La segunda sesión espera a que se complete la primera antes de continuar.
WITH (READPAST)
indica a SQL Server que simplemente omita las filas que están bloqueadas por otras sesiones. ¿Estás seguro de que quieres hacer eso? Además, ¿cuántas filas en esta tabla está modificando? Muéstrenos el esquema de la tabla (incluidos los índices) y laMERGE
declaración que está ejecutando.