it-swarm-fr.com

Pourquoi cette requête cause-t-elle une impasse?

Pourquoi cette requête cause-t-elle une impasse?

UPDATE TOP(1) system_Queue SET
  [StatusID] = 2,
  @ID = InternalID
WHERE InternalID IN (
    SELECT TOP 1 
      InternalID FROM system_Queue
    WHERE IsOutGoing = @IsOutGoing AND StatusID = 1
ORDER BY MessageID ASC, InternalID ASC)

Graphique Deadlock ajouté:

<keylock hobtid="72057594236436480" dbid="9" objectname="Z.dbo.system_Queue" indexname="PK_system_Queue" id="lock5b25cc80" mode="X" associatedObjectId="72057594236436480">
    <owner-list>
     <owner id="processc6fe40" mode="X"/>
    </owner-list>
    <waiter-list>
     <waiter id="processc7b8e8" mode="S" requestType="wait"/>
    </waiter-list>
   </keylock>
   <keylock hobtid="72057594405453824" dbid="9" objectname="Z.dbo.system_Queue" indexname="IX_system_Queue_DirectionByStatus" id="lock48cf3180" mode="S" associatedObjectId="72057594405453824">
    <owner-list>
     <owner id="processc7b8e8" mode="S"/>
    </owner-list>
    <waiter-list>
     <waiter id="processc6fe40" mode="X" requestType="wait"/>
    </waiter-list>
   </keylock>

Ajouté:

Merci Sankar pour l'article qui a des solutions Comment éviter ce type d'impasse:

  • éliminez les colonnes inutiles de la projection du lecteur, il n'est donc pas nécessaire de rechercher l'index en cluster
  • ajouter des colonnes requises sous forme de colonnes contenues sur l'index non clustered pour rendre l'index de revêtement, de nouveau pour que le lecteur n'a pas la recherche de l'index en cluster.
  • évitez les mises à jour qui doivent conserver l'indice non clustered
11
garik

Il me semble que si vous essayez de faire une sélection et une mise à jour dans la même instruction et sur la même table.

Le SELECT contient un verrou partagé sur les valeurs à l'intérieur de l'indice ix_system_queue_directionbystatus, ainsi que les besoins de mise à jour pour que ces serrures soient publiés avant de pouvoir obtenir une serrure exclusive qui mettra à jour la clé primaire (que je vais deviner. Ix_system_queue_directionbystatus clé de la clé).

Quoi qu'il en soit, je suppose que cette requête ne réussirait que sur les rares chances que les valeurs d'index qu'il sélectionne et que la mise à jour ne soit pas conflictuelle. Est-ce que c'est une manette de manœuvre chaque fois que vous exécutez (je suppose que ce serait).

Voici un lien qui explique des blocages plus en détail: http://sqlblog.com/blogs/jonathan_kehayias/archive/2008/07/30/Le-anatomy-of-a-deadlock.aspx

13
SQLRockstar

Je ne m'attends pas à ce que vous marquiez ce post comme réponse, mais partageez plus d'informations ici par d'autres experts SQL Server sur ce sujet.

http://sqlblog.com/blogs/alexander_kuznetsov/archive/2009/01/01/reproducing-deadlocks-involving-only-one-table.aspx

http://rusanu.com/2009/05/16/readwewrite-deadlock/

6
Sankar Reddy