Чому цей запит спричиняє тупик?


11

Чому цей запит спричиняє тупик?

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)

Додано графік тупикової ситуації:

<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>

ДОДАТО:

Дякую Sankar за статтю, в якій є рішення, як уникнути такого типу тупикової ситуації:

  • виключити непотрібні стовпці з проекції читача, щоб йому не потрібно було шукати кластерний індекс
  • додайте потрібні стовпці як містяться стовпці до некластеризованого індексу, щоб зробити індекс, що охоплює, знову, щоб читач не шукав кластерний індекс
  • уникайте оновлень, які мають підтримувати некластеризований індекс

яку версію платформи db ви використовуєте? який рівень ізоляції (або одночасності) trx за замовчуванням? Які індекси існують у таблиці system_Queue зараз?
SQLRockstar

@SQLRockstar додано частину графа тупикового зв'язку, sql server 2008
garik

@SQLRockstar IX_system_Queue_DirectionByStatus індекс за IsOutGoing та StatusID.
garik

Відповіді:


13

Мені це здається, ніби ви намагаєтесь зробити SELECT і UPDATE у тому самому операторі та в одній таблиці.

SELECT містить загальний замок на значеннях всередині індексу IX_system_Queue_DirectionByStatus, і UPDATE потребує звільнення цих замків, перш ніж він зможе отримати його ексклюзивний замок, який оновить первинний ключ (який, напевно, є кластером, а також частина Значення ключа IX_system_Queue_DirectionByStatus).

У будь-якому разі, я здогадуюсь, що цей запит матиме успіх лише за рідкісних випадків, коли значення індексу, які він вибирає та оновлює, не суперечать один одному. Чи це глухий кут щоразу, коли виконується (я припускаю, що це було б).

Ось посилання, яке детальніше пояснює тупикові місця: http://sqlblog.com/blogs/jonathan_kehayias/archive/2008/07/30/the-anatomy-of-a-deadlock.aspx


Бінго! Дякую. Це була справді дивна ситуація з тупиком, яку я ніколи не бачив. Дякую за відповідь
garik

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.