Problème d'interblocage de SQL Server 2005
-
22-07-2019 - |
Question
Je rencontre un problème d'interblocage lorsque j'essaie de verrouiller certains enregistrements de sorte qu'aucun processus (service Windows) ne sélectionne les éléments pour les traiter, puis met à jour le statut, puis renvoie un jeu d'enregistrements.
Pouvez-vous s'il vous plaît laissez-moi savoir pourquoi je reçois le problème de l'impasse lorsque cette procédure est invoquée?
CREATE PROCEDURE [dbo].[sp_LoadEventsTemp]
(
@RequestKey varchar(20),
@RequestType varchar(20),
@Status varchar(20),
@ScheduledDate smalldatetime = null
)
AS
BEGIN
declare @LoadEvents table
(
id int
)
BEGIN TRANSACTION
if (@scheduledDate is null)
Begin
insert into @LoadEvents (id)
(
Select eventqueueid FROM eventqueue
WITH (HOLDLOCK, ROWLOCK)
WHERE requestkey = @RequestKey
and requesttype = @RequestType
and [status] = @Status
)
END
else
BEGIN
insert into @LoadEvents (id)
(
Select eventqueueid FROM eventqueue
WITH (HOLDLOCK, ROWLOCK)
WHERE requestkey = @RequestKey
and requesttype = @RequestType
and [status] = @Status
and (convert(smalldatetime,scheduleddate) <= @ScheduledDate)
)
END
update eventqueue set [status] = 'InProgress'
where eventqueueid in (select id from @LoadEvents)
IF @@Error 0
BEGIN
ROLLBACK TRANSACTION
END
ELSE
BEGIN
COMMIT TRANSACTION
select * from eventqueue
where eventqueueid in (select id from @LoadEvents)
END
END
Merci d'avance.
La solution
Les blocages se produisent le plus souvent (selon mon expérience) lorsque différentes ressources sont verrouillées dans différentes transactions dans différents ordres.
Imaginez 2 processus utilisant les ressources A et B, mais en les verrouillant dans différents ordres.
- Le processus 1 verrouille la ressource A, puis la ressource B
- Le processus 2 verrouille la ressource B, puis la ressource A
Ce qui suit devient alors possible:
- Le processus 1 verrouille la ressource A
- Traiter 2 verrous de la ressource B
- Le processus 1 tente de verrouiller la ressource B, puis s’arrête et attend comme le processus 2 l’a demandé
- Le processus 2 tente de verrouiller la ressource A, puis s’arrête et attend comme le processus 1 l’a demandé
- Les deux processus s’attendent, Blocage
Dans votre cas, nous aurions besoin de voir exactement où le SP tombe en raison d'un blocage (la mise à jour, je suppose?) et de tout autre processus faisant référence à cette table. Il peut s'agir d'un déclencheur ou de quelque chose qui se trouve alors dans une impasse sur une table différente, pas sur la table que vous mettez à jour.
Ce que je voudrais faire est d'utiliser la la syntaxe de sortie de SQL Server 2005 . pour éviter d'avoir à utiliser la transaction ...
UPDATE
eventqueue
SET
status = 'InProgress'
WHERE
requestkey = @RequestKey
AND requesttype = @RequestType
AND status = @Status
AND (convert(smalldatetime,scheduleddate) <= @ScheduledDate OR @ScheduledDate IS NULL)
OUTPUT
inserted.*
Autres conseils
Avez-vous un index non-cluster défini comme:
CREATE NONCLUSTERED INDEX NC_eventqueue_requestkey_requesttype_status
ON eventqueue(requestkey, requesttype, status)
INCLUDE eventqueueid
et un autre sur eventqueueid?
BTW, la conversion de la colonne scheduleddate
en type smalldatetime
empêchera l'utilisation d'un index sur cette colonne.
Tout d’abord, lorsque vous utilisez SQL Server, je vous recommande d’installer Performance Dashboard, un outil très pratique pour identifier les verrous en cours de création sur le serveur.
Deuxièmement, tracez votre SQL Server à l’aide de SQL Profiler (Déjà installé) et assurez-vous d’avoir sélectionné dans la sélection des événements l’élément Verrous > Graphique d'interblocage indiquant la cause du blocage.
Vous devez avoir très clairement à l’esprit ce qui est une impasse pour commencer à le résoudre. Lorsque vous accédez à une table ou à une ligne de la base de données, un verrou est créé.
Permet d'appeler les SPID 51 et SPID 52 (SPID = ID de processus SQL)
SPID 51 verrouille la cellule A
SPID 52 verrouille la cellule B
si, sur la même transaction, le SPID 51 demande la cellule B, il attendra le SPID 52 jusqu'à ce qu'il le libère.
si, sur la même transaction, SPID 52 demande pour la cellule A, vous obtenez un blocage, car cette situation ne se terminera jamais (51 en attente de 52 et 52 en 51)
Je dois vous dire que ce n'est pas facile à résoudre, mais vous devez aller plus loin pour trouver la résolution