SQL Server блокируется между выбором / обновлением или множественным выбором

37
задан Rob West 19 March 2009 в 11:48
поделиться

7 ответов

Я когда-то отметил хорошую статью приблизительно Усовершенствованный SQL Server, блокирующий по SQL-Server-Performance.com. Та статья идет вне классической ситуации с мертвой блокировкой, что Вы упомянули и могли бы дать Вам некоторое понимание Вашей проблемы.

13
ответ дан MicSim 19 March 2009 в 11:48
поделиться
  • 1
    Lucene кажется действительно классным, спасибо за предложение! Но, да, КОНЕЧНО, I' m любопытный!:) – aquinas 25 March 2009 в 23:21

Читайте правильно на транзакциях и уровнях изоляции: для несколько плотного, но довольно полного и технологии нейтральная работа, см. Принципы Обработки транзакций . Это качало мой мир (и дал мне довольно много головных болей!).

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

Вы хотели бы, чтобы база данных ожидала, произвольно жаждут монопольной блокировки на Ваших данных? Смотрите на свои уровни изоляции повсюду, и выполняете ли Вы излишне ряд чтений как изолированная транзакция. Не всегда легко определить, как грязные чтения можно терпеть, хотя...

1
ответ дан Pontus Gagge 19 March 2009 в 11:48
поделиться
  • 1
    Только создатели Стандарта C++, действительно знают, почему это так. – Kirill V. Lyadvinsky 29 March 2010 в 23:35

Необходимо читать на изоляции транзакции: http://msdn.microsoft.com/en-us/library/ms173763.aspx

0
ответ дан James L 19 March 2009 в 11:48
поделиться
  • 1
    Это не ответ моего вопроса. При чтении моего вопроса Вы отметили бы, что я уже знаю, что явная специализация вложенного класса не позволяется. И я уже нашел способ обойти этот запрет. Мой вопрос был , Почему это так? – Gunther Piez 29 March 2010 в 23:32

Блокировки между едиными запросами могут произойти, поскольку они блокируют единственные строки, не всю таблицу:

запрос на обновление получает блокировку обновления на нескольких строках в таблице, и запрос Select добирается, чтение соединяют некоторые другие строки в таблице. Запрос на обновление тогда пытается получить блокировку обновления на строках, которые читаются заблокированные, и запрос Select пытается добраться, чтение соединяют строки, которые являются заблокированным обновлением.

Это может стать еще более сложным с блокировками escalading, т.е. база данных решает, что существует слишком много единственных строк, заблокированных транзакцией так, чтобы это было наращено в блокировку раздела таблицы или всей таблицы. Это означает, что блокировка может влиять на строки, которые непосредственно не вовлечены в запрос.

5
ответ дан Guffa 19 March 2009 в 11:48
поделиться
  • 1
    @litb: верный, и если в первые годы Andrew Koenig и Bjarne Stroustrup, встреченный в лифте, и никто не занял минуты, тогда кто знает, какие темные сделки, возможно, были заключены. Моя точка не то, что C++ совершенно прозрачен, просто это Kirill' s абсолютный оператор отчаянно нечистолюбиво, полагая, что во многих случаях решения, касающиеся C++, были переданы на публике бесконечно. Я понятия не имею, является ли это одним из них, я просто утомляюсь идеей, что дизайн языка - что-то, о чем у программистов нет бизнеса, пытающегося думать или быть любопытным на предмет. " Возвратитесь к работе, трудовая единица drhirsch";-) – Steve Jessop 10 April 2010 в 12:25

Это может произойти, потому что выбор берет блокировку на двух различных индексах, между тем обновление берет блокировку на тех же индексах в противоположном порядке. Выбору нужны два индекса, потому что первый индекс не покрывает все столбцы, к которым он должен получить доступ; для обновления нужны два индекса, потому что при обновлении столбца ключа индекса, необходимо взять блокировку на нем.

http://blogs.msdn.com/bartd/archive/2006/09/25/770928.aspx имеет фантастическое объяснение. Предложенные исправления включают добавление индекса, который покрывает все столбцы избранные потребности, переключаясь для создания снимков изоляции, или явно вынуждая выбор захватить блокировку обновления, в которой это обычно не нуждалось бы.

20
ответ дан 27 November 2019 в 04:48
поделиться

Я удивлен, что никто не упомянул подсказку блокировки WITH (UPDLOCK). Она очень полезна, если у вас возникают тупики, например, при параллельном выполнении двух пар select-insert.

В SQL Server, если вы выдаете селекты с WITH (UPDLOCK), второй селект будет ждать завершения первого селекта. В противном случае они получают общие блокировки, и когда они одновременно пытаются перейти на эксклюзивные блокировки, они заходят в тупик.

13
ответ дан 27 November 2019 в 04:48
поделиться

Я предполагаю, что оператор select требует блокировки чтения, когда вы идете с оператором update, его необходимо обновить до блокировки записи.

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

Если используется выборка для обновления (UPDLOCK), тогда с самого начала будет установлена ​​блокировка записи, и тогда у вас не будет проблемы с взаимоблокировкой.

5
ответ дан 27 November 2019 в 04:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: