MSSQL нюансы

Блокировки

В MSSQL есть следующие уровни изоляции данных:

  1. read uncommitted (неподтвержденное чтение - грязное чтение)
  2. read committed (подтвержденное чтение)
  3. repeatable read (повторяемое чтение)
  4. serializable (упорядоченный или сериализуемый)
  5. read committed snapshot (подтвержденное чтение с включенным параметром READ_COMMITTED_SNAPSHOT)
  6. snapshot (изоляция моментального снимка)

По-умолчанию включен режим read committed (подтвержденное чтение), при котором операции insert, update, delete блокируют затрагиваемые строки в таблице, поэтому операция select встает в очередь ожидания разрблокировки (пока ресурс не освободится), но, у операции select есть 2 хинта (указателя), благодаря которым можно из заблокированой таблицы вычитывать строки:

WITH(READPAST) - читать зафиксированные строки (будут игнорироваться строки подвергающиеся добавлению/изменению/удалению в транзакциях сторонних сессий) - блокирует вычитываемые строки (накладывая S блокировку)

WITH(NOLOCK) - читать незафиксированные строки (грязные данные) - не блокирует вычитываемые строки (блокировки не накладываются)

Если нужен WITH(NOLOCK) для всех запросов транзакции, тогда нужно перед началом транзакции указать уровень блокировки READ UNCOMMITTED, например так:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRAN;

Как блокировать

Существуют следующие виды блокировок:

Вид Какие операции блокирует Что именно блокирует
Exclusive lock (X) Insert, Update, Delete блокировка страницы или строки
Shared lock (S) Insert, Update, Delete, Select блокировка страницы или строки
Update lock (U) Insert, Update, Delete блокировка страницы или строки, которая заблокирована с помощью Shared lock (S)
Intent locks (I):   намеренье о блокировки таблицы целиком, может быть следующим:
– Intent exclusive (IX) Insert, Update, Delete см. выше
– Intent shared (IS) Insert, Update, Delete, Select см. выше 
– Intent update (IU) Insert, Update, Delete см. выше 

К примеру, чтобы исключить простейший случай дедлока, перед UPDATE нужных ID-строк, хорошей практикой считается - блокировка этих ID-строк с помощью SELECT-a:

SELECT id FROM my_table WITH(UPDLOCK,READPAST) WHERE id IN (1,2,...)

и затем сверить кол-во возвращенных ID-строк (если кол-во возвращенных SELECT-ом строк равно кол-ву ID-строк в операторе IN, то все указанные строки были заблокированы в рамках текущей транзакции - BEGIN TRAN должен быть вызван до SELECT-a блокировки).

Источник: 1 - 2 - 3

Оцени публикацию:
  • 0,0
Оценили: 0


Предложения и пожелания:

 

youtube.com/watch?v=7hFivbgIEqk

При полном или частичном использовании материалов данного сайта, ссылка на сайт "yapro.ru" обязательна как на источник информации.
Автоматический импорт материалов и информации с сайта запрещен.
Copyrights © 2007 - 2019 YaPro.Ru

Лебеденко Николай Николаевич
Ошибка в тексте? Выделите её мышкой и нажмите: Ctrl + Enter