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.

Était-ce utile?

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.

scroll top