Блокирует ли сериализуемый уровень изоляции SQL Server всю таблицу

9

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

Я не могу найти ничего в документах для "всей таблицы блокировок": SET TRANSACTION ISOLATION LEVEL .

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

Я совершенно не прав здесь? Это фактически блокирует всю таблицу (или таблицы)?

mslot
источник

Ответы:

16

Эскалация, хотя

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

  • Правильные индексы могут помочь избежать эскалации блокировки до определенной точки
  • Блокировка многих индексов увеличит вероятность повышения блокировки; количество суммируется по объектам для одного оператора

Несколько быстрых примеров использования одной таблицы с одним индексом. Идентификатор является первичным ключом и кластеризованным индексом в таблице.

Одна строка

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id = 138; --One value

ROLLBACK

Для одного значения Id блокировка минимальна.

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| RangeX-X     | Comments      | KEY           |           1 |
| IX           | Comments      | OBJECT        |           1 |
| IX           | Comments      | PAGE          |           1 |
+--------------+---------------+---------------+-------------+

Несколько строк

Но блокировки возрастут, если мы начнем работать в диапазонах:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id BETWEEN 1 AND 5000; -- Small range

ROLLBACK

Теперь у нас есть больше эксклюзивных замков на большем количестве ключей:

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| RangeX-X     | Comments      | KEY           |        2429 |
| IX           | Comments      | OBJECT        |           1 |
| IX           | Comments      | PAGE          |          97 |
+--------------+---------------+---------------+-------------+

Намного больше рядов

Это будет продолжаться, пока мы не достигнем переломного момента:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id BETWEEN 1 AND 11655; --Larger range

ROLLBACK

Попытка эскалации блокировки выполнена успешно:

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| X            | Comments      | OBJECT        |           1 |
+--------------+---------------+---------------+-------------+

Обращать внимание

Здесь важно разделить две концепции: уровень изоляции будет сериализуемым, независимо от типа блокировок. Запрос выбирает уровень изоляции, а механизм хранения выбирает блокировки. Сериализуемый не всегда приводит к блокировкам диапазона - механизм хранения может выбрать любой тип блокировки, который все еще соответствует уровню изоляции.

Эрик Дарлинг
источник
5

Если в предикате поиска есть индекс, его можно использовать для блокировки диапазона .

Т.е. блокировка от первого ряда до следующего в диапазоне. И от этого до третьего ряда и т. Д. До последнего ряда в диапазоне. Таким образом, по сути, ряд блокировок строк, но он блокирует диапазон от вставок также для «промежуточных» значений (блокировка диапазона).

Для этого у вас (SQL Server) должен быть индекс для работы. Без индексов для блокировки (индексов по предикатам) вы (из того, что я знаю) получат блокировки таблиц.

Тибор Караси
источник