SQL Server ROWLOCK über einen SELECT falls vorhanden nicht INSERT-Transaktion
-
30-09-2019 - |
Frage
Ich habe von SQL Server aktualisieren 2005 bis 2008. Ich erinnere mich, dass im Jahr 2005, ROWLOCK nicht einfach Arbeit und ich hatte PageLock oder XLOCK zu verwenden, um jede Art von tatsächlichen Verriegelung zu erreichen. Ich weiß, dass ein Leser dieser fragen: „Was haben Sie falsch gemacht?“ Nichts. Ich schlüssig bewiesen, dass ich ein „ROWLOCKED“ Zeile bearbeiten konnte, konnte aber nicht, wenn ich die Sperre Ebene eskaliert. Ich hatte keine Chance, um zu sehen, ob das funktioniert in SQL 2008. Meine erste Frage ist, hat jemand im Jahr 2008 über dieses Thema kommen?
Die zweite Frage ist, folgt als. Ich möchte testen, ob ein Wert vorhanden ist und wenn ja, führen Sie eine Aktualisierung der relevanten Spalten, anstatt einen Einsatz der ganzen Reihe. Dies bedeutet, dass, wenn die Zeile gefunden wird es als Wartungsprozedur gesperrt werden muss, könnte diese Reihe Mitte Prozess löschen, einen Fehler zu verursachen.
Um das Prinzip zu veranschaulichen, wird der folgende Code funktioniert?
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
Lösung
Eine Erklärung ...
- ROWLOCK / PageLock heißt Granularität
- XLOCK ist Modus
Granularität und Isolationsstufe und Modus sind orthogonal.
-
Granularität = was ist gesperrt = Zeile, Seite, Tabelle (
PAGLOCK, ROWLOCK, TABLOCK
) -
Isolation Level = Sperre Dauer, Gleichzeitigkeit (
HOLDLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE
) -
Mode = Sharing / Exklusivität (
UPDLOCK, XLOCK
) -
"combined" zB
NOLOCK, TABLOCKX
XLOCK hätte die Reihe exklusiv gesperrt, wie Sie wollen. ROWLOCK / PageLock hätte nicht.