Как один SELECT блокирует другой?

Я смотрю на вывод SP_WhoIsActive на SQL Server 2005, и он сообщает мне, что один сеанс блокирует другой - хорошо. Однако они оба выполняют SELECT. Как один SELECT блокирует другой? Разве они оба не должны получать общие блокировки (которые совместимы друг с другом)?

Еще несколько деталей: ни один из сеансов не имеет счетчика открытых транзакций, поэтому они являются автономными.

Запросы соединяют представление с таблицей.

Это сложные запросы, которые объединяют множество таблиц и приводят к примерно 10 000 чтений.

Любое понимание очень ценится.


person Krip    schedule 08.06.2010    source источник


Ответы (2)


Операторы SELECT могут блокировать другой оператор SELECT. Вы, вероятно, думаете, что, поскольку оба получают только S-блокировки, они никогда не должны блокировать. Но блокировка происходит не только на блокировках, но и на разных типах ресурсов. Типичный пример - ограничения памяти. Я попытаюсь выкопать недавний ответ на вопрос здесь, в котором был прикреплен график тупиковых ситуаций, показывающий операторы SELECT, один из которых ожидает другого для ресурсов памяти (буферов) оператора параллельного обмена.

Обновлено Вот ссылка с информацией о взаимоблокировке, о которой я говорил: У меня есть данные о взаимоблокировках, но я не могу понять, почему они возникают Если вы изучите график взаимоблокировок, вы заметите следующий ресурс в списке ожидания:

<exchangeEvent id="Pipe894b0680" WaitType="e_waitPipeGetRow" nodeId="0">
  <owner-list>
    <owner id="process824df048"/>
  </owner-list>
  <waiter-list>
    <waiter id="process86ce0988"/>
  </waiter-list>
</exchangeEvent>

Это не блокировка, это ресурс 'e_waitPipeGetRow', он принадлежит SELECT, и его ожидает другой SELECT. Некоторое обсуждение «параллельных ресурсов внутри запроса» можно найти здесь: Сегодняшний досадно-громоздкий термин:" взаимоблокировки параллельных потоков внутри запроса ". Хотя большинство обсуждений будет сосредоточено на проблемах взаимоблокировки, это не означает, что обычная блокировка не может происходить на этих ресурсах. sys.dm_exec_requests будет содержать правильную информацию в wait_type и wait_resource.

person Remus Rusanu    schedule 08.06.2010

Я думаю, это потому, что первый выбор выполняет блокировку строки / блокировку таблицы. Присоединяясь к столу, вы можете предоставить подсказку NO LOCK.

person Chinjoo    schedule 08.06.2010
comment
По моему сегодняшнему опыту, подсказки NO LOCK недостаточно, чтобы остановить реальное событие взаимоблокировки параллельного потока внутри запроса. - person Cody Konior; 19.04.2013
comment
Не рекомендуется использовать NO LOCK. Это может привести к грязному чтению (дублирование данных, отсутствие данных). Блокировка - это преднамеренный механизм для сохранения согласованности данных. Используйте NO LOCK на свой страх и риск. blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere - person Davos; 04.08.2015