Мертвые блокировки - это действительно поможет?

Таким образом, у меня есть запрос, который продолжает заходить в тупик на мне. Люди, которые знают систему хорошо, не могут выяснить, почему sproc заходит в тупик, но они говорят мне, что я должен просто добавить это к нему:

SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Это - действительно допустимое решение? Что это делает?

7
задан Matt Grande 30 July 2010 в 17:56
поделиться

5 ответов

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Это приведет к тому, что система будет возвращать несогласованные данные, включая повторяющиеся и отсутствующие записи. Подробнее см. Ранее зафиксированные строки могут быть пропущены, если используется подсказка NOLOCK , или здесь, в Timebomb - Проблема согласованности с NOLOCK / READ UNCOMMITTED .

Тупиковые ситуации можно исследовать и устранять, это не имеет большого значения, если вы следуете надлежащей процедуре. Конечно, «грязное чтение» может показаться проще, но в дальнейшем вы будете сидеть долгие часы, глядя на свою главную бухгалтерскую книгу и задаваясь вопросом, какого черта она делает , а не балансовых дебетов и кредитов. Так что читайте еще раз, пока не поймете это: ГРЯЗНЫЕ ЧТЕНИЯ ЯВЛЯЮТСЯ НЕСООТВЕТСТВЕННЫМИ ЧТЕНИЯМИ .

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

ALTER DATABASE MyDatabase
SET READ_COMMITTED_SNAPSHOT ON

Но имейте в виду, что изоляция снимков не исправляет тупиковые ситуации, она только скрывает их. Правильное расследование причины тупиковой ситуации и ее устранение всегда является правильным действием.

6
ответ дан 6 December 2019 в 12:45
поделиться

Случайное добавление параметров SET в запрос вряд ли поможет. Боюсь,

SET NOCOUNT ON

не повлияет на проблему.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

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

Решит ли это вашу проблему тупиковой ситуации, зависит от ее типа. Это не будет иметь никакого эффекта, если проблема заключается в взаимоблокировке двух писателей из-за нелинейного упорядочения запросов блокировки. (транзакция 1 обновляет строку a, транзакция 2 обновляет строку b, затем tran 1 запрашивает блокировку на b и tran 2 запрашивает блокировку на a)

Можете ли вы опубликовать проблемный запрос и график взаимоблокировок? (если вы используете SQL 2005 или новее)

3
ответ дан 6 December 2019 в 12:45
поделиться

NOCOUNT не позволит вашему запросу возвращать количество строк обратно в вызывающее приложение (т. Е. Затронуто 1000000 строк).

TRANSACTION ISOLATION LEVEL READ UNCOMMITTED допускает «грязные» чтения, как указано здесь .

Уровень изоляции может помочь, но вы хотите разрешить грязное чтение?

5
ответ дан 6 December 2019 в 12:45
поделиться

Лучшее руководство:

http://technet.microsoft.com/es-es/library/ms173763.aspx

Фрагмент:

Указывает, что операторы могут читать строки, которые были изменены другими транзакции, но еще не совершенные.

Транзакции, выполняющиеся в READ НЕОБХОДИМЫЙ уровень не выдаёт общий блокировки для предотвращения других транзакций от изменения данных, прочитанных текущая сделка. ПРОЧИТАЙТЕ НЕПРЕРЫВНО транзакции также не блокируются эксклюзивные блокировки, которые предотвратят текущая транзакция из чтения строк которые были изменены, но не совершенные другими сделками. Когда эта опция установлена, можно читать незафиксированные модификации, которые называются грязным чтением. Ценности в данные могут быть изменены, а строки могут появляются или исчезают в наборе данных до окончания сделки. Эта опция имеет тот же эффект, что и установка NOLOCK на всех столах во всех Операторы SELECT в транзакции. Это наименее ограничительный из уровни изоляции.

В SQL Server вы также можете минимизировать блокировка разногласий при защите транзакции из грязных чтений незафиксированные изменения данных с использованием либо:

Уровень изоляции READ COMMITTED с READ_COMMITTED_SNAPSHOT опция базы данных установлена ​​в положение ON. В Уровень изоляции SNAPSHOT

.

2
ответ дан 6 December 2019 в 12:45
поделиться

С другой стороны, есть два других аспекта, которые могут помочь.

1) Индексы и индексы, используемые SQL. Стратегия индексации, используемая в таблицах, повлияет на количество затронутых строк. Если вы вносите изменения в данные с использованием уникального индекса, вы можете снизить вероятность возникновения взаимоблокировок.

Алгоритм один - конечно, он не сработает во всех случаях. Использование NOLOCK является целевым, а не глобальным.

The "old" way:
UPDATE dbo.change_table
   SET somecol = newval
 WHERE non_unique_value = 'something'

The "new" way:
INSERT INTO #temp_table
    SELECT uid FROM dbo.change_table WITH (NOLOCK)
     WHERE non_unique_value = 'something'

UPDATE dbo.change_table
   SET somecol = newval
  FROM dbo.change_table c
       INNER JOIN
       #temp_table t
       ON (c.uid = t.uid)

2) Продолжительность транзакции Чем дольше открыта транзакция, тем выше вероятность возникновения разногласий. Если есть способ сократить время, в течение которого записи остаются заблокированными, вы можете снизить вероятность возникновения взаимоблокировки. Например, выполните столько же операторов SELECT (например, поисков) в начале кода вместо выполнения INSERT или UPDATE, затем поиска, затем INSERT, а затем еще одного поиска. Здесь можно использовать подсказку NOLOCK для SELECT в «статических» таблицах, которые не изменяются, уменьшая «след» блокировки кода.

0
ответ дан 6 December 2019 в 12:45
поделиться
Другие вопросы по тегам:

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