Я читал большой объем информации о тупиках в Интернете, чтобы быть уверенным, что я не задаю глупый вопрос. Следующая таблица, где происходят тупики, служит в очереди заказов. Никакие записи фактически не удаляются, только их изменения статуса, т. Е. ОБРАБОТКА, ОТМЕНА, ЗАВЕРШЕНО. Я наблюдаю таинственные тупики на SELECTs with UPDLOCK
на этой таблице. Единственная особенность, которую я вижу в SELECT, - это внутренний SELECT without UPDLOCK
, но это не имеет значения. В таблице включена блокировка строк. Эти SELECTS запускаются параллельно, отдельными планировщиками заданий. Смысл такого SELECT заключается в том, что он извлекает первый (самый ранний) порядок, имеющий один или несколько указанных статусов (вышеупомянутое «ОБРАБОТКА, ОТМЕНА, ЗАВЕРШЕНО»). Заказ с минимальным ID (минимальный идентификатор выбирается вручную, в запросах ниже 6850000) считается «первым» заказом. Это делается по соображениям производительности. Вот фактический ВЫБОР:Очень таинственный тупик
select * from TORDERSUMMARY with (updlock, rowlock)
where ID in
(select min(ID) from TORDERSUMMARY
where ID > 6850000 and (ORDERSTATUS in ('INITIATED'))
and (ORDERDISPATCHSTATUS in (0 , 2 , 4)) and (ORDERGROUPID is null))
В таблице указан кластерный индекс, определенный для первичного ключа, идентификатора. Как указано в SQL Server Management Studio 2008, оценочный и фактический план выполнения таких запросов - CLUSTERED INDEX SEEK. В таблице есть несколько некластеризованных индексов, и я надеялся, что операция индекса НК будет блокироваться с помощью операции с кластерным индексом (я подробно прочитал о ряде таких случаев в сети), но поскольку только кластерный индекс используется наилучшим образом (поиск индекса), причина, похоже, не лежит там.
Внутренний SELECT не имеет подсказок UPDLOCK, ROWLOCK, поэтому при блокировке не выбирается несколько записей. Я не могу представить ни одного сценария, где два таких выбора будут заторможены. Подсказка UPDLOCK, конечно, состоит в том, что впоследствии код пытается обновить статус заказа (отметить его как обработанный и т. Д.).
Вот один тупиковый XDL-файл от SQL Server Management Studio 2008 - http://pastebin.com/ugCUbn80. Сам сервер 9.0.4035. SQL-запросы длинны, поэтому по какой-либо причине они усекаются в XDL-файле, но SELECTs, безусловно, относятся к вышеуказанному типу, потому что я провел ручные стресс-тесты сервера с такими SELECT, и тупик, казалось бы, случайным образом происходит в одном и том же путь.
Технически это было бы мнение не правило :). Есть несколько очень веских причин для создания вашего кластерного индекса по естественному ключу, однако они являются одними и теми же вескими причинами, почему вы должны создавать его на искусственном ключе. –