Может ли кто -нибудь объяснить, зачем выбирать с NoLock, запросит зелье обновленных данных?

dba.stackexchange https://dba.stackexchange.com/questions/11571

  •  16-10-2019
  •  | 
  •  

Вопрос

Я читал ответ от здесь (Из Stackoverflow, я думаю, должен спросить здесь)

Нолок означает не размещать замки вообще.

Ваш запрос может возвращать части данных до обновления и порций по состоянию на обновление в одном запросе.

Я получаю, что Нолок не будет помещать замок на стол, поэтому другие люди могут запрашивать в то же время.

Из ответа и примера он показывает, он получает данные, пока данные обновляются.

Почему это происходит?

Я предполагаю, что для обычного выбора он попробует разместить блокировку на таблице, поэтому при выполнении оператора обновления он помещает блокировку на строке или странице. Затем, когда я пытаюсь запустить оператор SELECT, он не может поместить блокировку, пока не будет выпущена блокировка оператора обновления.

Но в этом случае, потому что оператор SELECT не пытается помещать блокировку на таблицу, поэтому он может работать, не дожидаясь оператора обновления, выпустите блокировку?

Это было полезно?

Решение

Это не совсем правда, что NOLOCK означает не размещать замки вообще. Запросы под этой подсказкой все равно потребуются Sch-S замки и (возможно HOBT замки).

Под read committed Уровень изоляции SQL Server Will (обычно) взять уровень ряда S блокирует и выпустите их, как только данные будут прочитаны. Они несовместимы с X замки удерживаются на бескомпромиссных обновлениях и, таким образом, предотвращают грязные чтения.

В примере в связанном ответе SELECT Запрос не заблокирован, когда он встречает модифицированную строку, поэтому чтение частичных обновлений вполне вероятно.

Это также может произойти по умолчанию read committed Уровень изоляции тоже, хотя SELECT читает несколько строк со значением «до» и других со значением «после». Это просто необходимо разработать ситуацию, когда

  1. Выберите запрос чтения значения строки R1 и выпускает его S замок
  2. Обновление обновлений запроса R2 и принимает X замок
  3. Выберите запрос, пытается прочитать R2 и заблокирован.
  4. Обновление обновлений запроса R1 и принимает X замок.
  5. Обновление транзакции коммиты, выпуская его блокировки и позволяя выбору читать R2

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

Пример

CREATE TABLE T
(
X INT IDENTITY PRIMARY KEY,
Y AS -X UNIQUE,
Name varchar(10),
Filler char(4000) DEFAULT 'X'
)


INSERT INTO T (Name)
SELECT TOP 2500 'A'
FROM master..spt_values

Теперь в одном окне запроса запуска

DECLARE @Sum int

SELECT 'SET @@ROWCOUNT' WHERE 1=0

WHILE (@@ROWCOUNT = 0)
SELECT @Sum = SUM(LEN(Name))
FROM T 
WHERE Y IN (-1, -2500)
HAVING SUM(LEN(Name)) = 3

Это будет работать в бесконечной петле. В другом забеге

UPDATE T 
SET Name=CASE WHEN Name = 'A' THEN 'AA' ELSE 'A' END

Это, вероятно, остановит петлю в другом запросе (попробуйте еще раз, если нет), что означает, что он должен был прочитать тоже A,AA или же AA,A

Другие советы

Намек NOLOCK эквивалентен уровню изоляции транзакций READ UNCOMMITTED, просто ограниченным применением одного метода доступа к таблице.

Что это делает, это делает не связанный появляться на вашем результате? Хм, на самом деле это вопрос »Что это не делает. Анкет Я объясню ниже.

Ну, это грубое упрощение, я знаю) MSSQL (по поведению по умолчанию) - это двигатель блокировки, что означает, что он использует блокировку для чтения/записи данных в постоянном порядке. В этом упрощенном объяснении MSSQL использует два вида замков: Общий замок а также Эксклюзивный замок.

Общий (ы) блокировка - это блокировка, которая позволяет прочитать ресурс (который может быть строкой, страницей строк или даже всей таблицы), но не позволяет записать к нему. Таким образом, если транзакция T1 помещает S Lock на R1 Row, все транзакции, которые пытаются прочитать R1, получит это чтение, но в то время как S Lock жив, никто не может написать R1.

Эксклюзивный (x) блокировка является аналогом общего блокировки. Это допускает эксклюзивный доступ к ресурсу - никакая другая транзакция не может читать или писать, кроме той, которая получила X Lock. В приведенном выше примере, если T1 получил не S Lock, а x Lock на R1, Никто, кроме T1, не может читать или написать это.

Это теория. Уровни изоляции уважают замки и уважают их распространенность и характеристики. Все, кроме READ UNCOMMITTED. Анкет Это просто дает * (поместите ваше плохое слово о ваших предпочтениях здесь) в замки относительно чтения - вы все еще не можете обновить строку, что еще одна транзакция получила x Lock. Это просто говорит: «Я прочитаю все, что имеет отношение к плану запроса - не обращайте внимания на то, что на нем».И сделай это.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top