Причина процесса, являющегося жертвой тупика



У меня процесс выбора занимает много времени, порядка от 5 до 10 минут.
в настоящее время я не использую NOLOCK в качестве подсказки для MS SQL database engine.
в то же время у нас есть другой процесс, выполняющий обновления и вставки в ту же базу данных и те же таблицы.
первый процесс начался, недавно, чтобы закончить преждевременно с сообщением




SQLEXCEPTION: транзакция была заблокирована на блокировке ресурсов с другим процессом и был выбран в качестве тупиковой жертвы.




этот первый процесс выполняется на других сайтах в идентичных условиях, но с меньшими базами данных, и поэтому рассматриваемый оператор select занимает гораздо более короткий период времени (порядка 30 секунд или около того). На этих других сайтах я не получаю сообщение о взаимоблокировке на этих других сайтах. Я также не получил это сообщение на сайте, который изначально имеет проблему, но, я предполагаю, что по мере роста базы данных я считаю Должно быть, я переступил какой-то порог. Вот мои вопросы:




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

  2. если я выполню выбор с подсказкой NOLOCK, это устранит проблему?

  3. я подозреваю, что поле datetime, которое проверяется как часть предложения WHERE в инструкции select, вызывает медленное время поиска. Могу ли я создать индекс на основе это поле? Это целесообразно?

532   3  

3 ответов:

Q1: может ли время, необходимое для выполнения транзакции, сделать связанный процесс более вероятным, чтобы он был помечен как жертва взаимоблокировки.

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

по умолчанию компонент Database Engine выбирает в качестве жертвы взаимоблокировки сеанс выполнения транзакции, которая является крайней мере дорого откатить. Кроме того, пользователь может задать приоритет сеансов в тупиковая ситуация с использованием SET DEADLOCK_PRIORITY заявление. DEADLOCK_PRIORITY может быть установлен в низкий, нормальный или высокий, или альтернативно можно задать любое целочисленное значение в диапазоне (от -10 до 10).

Q2. Если я выполню select с подсказкой NOLOCK, это устранит проблему?

нет. По нескольким причинам:

Q3. Я подозреваю, что поле datetime, которое проверяется как часть предложение WHERE в инструкции select вызывает медленное время поиска. Могу ли я создать индекс на основе этого поля? Это целесообразно?

наверное. Причиной тупика почти наверняка является плохо индексированная база данных.10 минут запросы приемлемы в таких узких условиях, что я на 100% уверен, что в вашем случае это не приемлемо.

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

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

ответы здесь стоит попробовать, но вы также должны просмотреть свой код. В частности, вы можете прочитать ответ Polyfun здесь: Как избавиться от взаимоблокировки в приложении SQL Server 2005 и C#?

Это объясняет проблему параллелизма и то, как использование "with (updlock)" в ваших запросах может исправить ситуацию взаимоблокировки - в зависимости от того, что именно делает ваш код. Если ваш код следует этому шаблону, это, вероятно, лучше исправить, прежде чем прибегая к грязным читает и т. д.

Comments

    Ничего не найдено.