2

J'ai une table qui contient les temps de connexion et de déconnexion des clients.Comment éviter les blocages sur des instructions de mise à jour simples?

ID  int 
ClientID int 
BeginDate datetime 
EndDate datetime 

Lorsqu'un client est connecté, un Session enregistrement est créé avec sa EndDate est nulle.

INSERT Session(ClientID, BeginDate, EndDate) 
VALUES(@ClientID, GETDATE(), null) 

Lorsque le client est déconnecté, mettre à jour la session il est donc EndDate contient le temps de déconnexion.

UPDATE Session 
SET EndDate = GETDATE() 
WHERE Id  = @SessionID 

Mais cela n'est pas toujours appelé. Donc, pour m'assurer que le même client n'a pas plus d'une session en même temps, j'exécute cette requête avant d'insérer une nouvelle session.

UPDATE Session 
SET EndDate  = GETDATE() 
WHERE ClientID = @ClientID 
and EndDate  is null 

Ce qui provoque un blocage lorsque plusieurs clients se connectent en même temps, selon le deadlock graph.

Je ne comprends pas pourquoi cela provoque un blocage,
Je ne comprends même pas pourquoi cette requête a besoin d'un verrou.
Qu'est-ce que je fais de mal?

Répondre

1

La mise à jour de EndDate à chaque fois avant d'en insérer ne semble pas être une bonne idée. Vous pouvez verrouiller la table même si aucune mise à jour n'est effectuée. Vous devez vérifier s'il existe une session où endate est null pour un client donné avant la mise à jour. Vous pouvez utiliser l'indicateur NoLock pour lire les données non validées .

Cette vérification minimisera le verrouillage causé par cette requête. Prévenir vaut mieux que guérir :)

+0

+1, je sélectionne simplement l'ID 'with (nolock)' maintenant et ne met à jour la table que si nécessaire. Ca a marché comme un charme, merci. –

1

bien qu'une instruction de mise à jour fait des X-verrous, pour cette instruction peut-être même une page ou un verrou de table, vous pouvez essayer de sélectionner les ID des sessions ouvertes et d'exécuter une mise à jour pour ces cela, qui est plus susceptible de ne verrouiller que ces lignes. Cela dépend aussi de votre niveau d'isolement.

ne peut pas y avoir plus d'une session ouverte, et si (et je devine qu'il s'agit d'une application web) un utilisateur ouvre le site avec 2 navigateurs web différents.

+0

+1 et merci. Deadlock graphique a déclaré que c'est un verrouillage de la page et oui, la sélection de l'ID a d'abord travaillé. J'ai accepté la réponse de ARS à cause de sa recommandation «nolock». Avant d'utiliser cela, la requête 'select' a également provoqué des blocages. À propos des sessions, ce n'est pas un site Web, c'est un service Windows que nos appareils GPRS se connectent, donc un appareil ne peut pas être connecté plusieurs fois en même temps. –

Questions connexes