SQL Server ROWLOCK sur SELECT si existe non transaction INSERT
-
30-09-2019 - |
Question
Je l'ai mis à jour de SQL Server 2005 à 2008. Je me souviens qu'en 2005, ROWLOCK n'a tout simplement pas le travail et je devais utiliser PageLock ou XLOCK pour réaliser tout type de verrouillage réel. Je connais un lecteur de ce demandera « qu'avez-vous fait mal? » Rien. Je prouvé de façon concluante que je pouvais modifier une ligne « ROWLOCKED », mais ne pouvait pas si j'escaladé le niveau de verrouillage. Je ne l'ai pas eu la chance de voir si cela fonctionne dans SQL 2008. Ma première question est quelqu'un a rencontré ce problème en 2008?
Ma deuxième question est suit comme. Je veux tester si une valeur existe et le cas échéant, effectuer une mise à jour sur les colonnes pertinentes, plutôt que d'un insert de la ligne entière. Cela signifie que si la ligne se trouve, il doit être verrouillé comme une procédure de maintenance pourrait supprimer cette mi-processus de ligne, ce qui provoque une erreur.
Pour illustrer le principe, fonctionnera le code suivant?
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
La solution
Une explication ...
- ROWLOCK / PageLock est-granularité
- XLOCK est le mode
Granularité et le niveau d'isolement et le mode sont orthogonaux.
-
granularity = ce qui est verrouillé = ligne, page, tableau (
PAGLOCK, ROWLOCK, TABLOCK
) -
Isolation Level = durée de verrouillage, la simultanéité (
HOLDLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE
) -
Mode = partage / exclusivité (
UPDLOCK, XLOCK
) -
"combiné" par exemple
NOLOCK, TABLOCKX
XLOCK aurait bloqué la ligne exclusivement comme vous voulez. ne serait pas ROWLOCK / PageLock.