SQL Server ROWLOCK sobre un SELECT si no existe transacción INSERT
-
30-09-2019 - |
Pregunta
He actualizado desde SQL Server 2005 a 2008. Recuerdo que en 2005, ROWLOCK simplemente no funcionaba y tuve que usar PageLock o XLOCK para lograr cualquier tipo de bloqueo real. Conozco a un lector de este preguntará "¿qué hiciste mal?" Nada. Yo probé manera concluyente que podría editar una fila "ROWLOCKED", pero no podía si aumentado el nivel de bloqueo. No he tenido la oportunidad de ver si esto funciona en SQL 2008. Mi primera pregunta es ¿alguien ha encontrado con este problema en 2008?
Mi segunda pregunta es la siguiente. Quiero probar si existe un valor y si es así, lleve a cabo una actualización de las columnas correspondientes, en lugar de una inserción de toda la fila. Esto significa que si no se encuentra la fila que necesita estar encerrado como un procedimiento de mantenimiento podría eliminar esta fila mitad del proceso, causando un error.
Para ilustrar el principio, ¿Funcionará el siguiente código?
BEGIN TRAN
SELECT ProfileID
FROM dbo.UseSessions
WITH (ROWLOCK)
WHERE (ProfileID = @ProfileID)
OPTION (OPTIMIZE FOR (@ProfileID UNKNOWN))
if @@ROWCOUNT = 0 begin
INSERT INTO dbo.UserSessions (ProfileID, SessionID)
VALUES (@ProfileID, @SessionID)
end else begin
UPDATE dbo.UserSessions
SET SessionID = @SessionID, Created = GETDATE()
WHERE (ProfileID = @ProfileID)
end
COMMIT TRAN
Solución
Una explicación ...
- ROWLOCK / PageLock es decir granularidad
- XLOCK es el modo
Granularidad y aislamiento nivel y el modo son ortogonales.
-
= Granularidad lo que está bloqueado = fila, página, mesa (
PAGLOCK, ROWLOCK, TABLOCK
) -
nivel de aislamiento = Duración de bloqueo, de concurrencia (
HOLDLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE
) -
Mode = compartir / exclusividad (
UPDLOCK, XLOCK
) -
"combinado" por ejemplo
NOLOCK, TABLOCKX
XLOCK habría bloqueado la fila exclusivamente como desee. ROWLOCK / PageLock no tendría.