SQL Server ROWLOCK sopra un SELECT, se non esiste transazione INSERT
-
30-09-2019 - |
Domanda
Ho aggiornato da SQL Server 2005 al 2008. Mi ricordo che nel 2005, ROWLOCK semplicemente non ha funzionato e ho dovuto usare PageLock o XLOCK per realizzare qualsiasi tipo di blocco vero e proprio. Conosco un lettore di questo chiederà "che cosa hai fatto di sbagliato?" Niente. I conclusivamente dimostrato che ho potuto modificare una riga "ROWLOCKED", ma non poteva se intensificato il livello di blocco. Non ho avuto la possibilità di vedere se questo funziona in SQL 2008. La mia prima domanda è qualcuno ha incontrato questo problema nel 2008?
La mia seconda domanda è la seguente. Voglio testare se esiste un valore e, se così, eseguire un aggiornamento su colonne pertinenti, piuttosto che un inserto dell'intera riga. Ciò significa che se si trova la riga che deve essere bloccato come una procedura di manutenzione potrebbe eliminare l'intermedio processo fila, causando un errore.
Per illustrare il principio, sarà il seguente lavoro codice?
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
Soluzione
Una spiegazione ...
- ROWLOCK / PageLock IS granularità
- XLOCK è la modalità
La granularità e l'isolamento di livello e la modalità sono ortogonali.
-
= granularità ciò è bloccato = riga, pagina, tavolo (
PAGLOCK, ROWLOCK, TABLOCK
) -
Livello di isolamento = durata di blocco, la concorrenza (
HOLDLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE
) -
Mode = condivisione / esclusività (
UPDLOCK, XLOCK
) -
"combinato", ad esempio
NOLOCK, TABLOCKX
XLOCK avrebbe bloccato la riga esclusivamente come si desidera. ROWLOCK / PageLock non avrebbe.