20. Гранулярность блокировок, иерархии блокировок и эскалация блокировок - KattyOG/Database GitHub Wiki
Общие сведения о блокировках
Блокировка - это механизм, с помощью которого компонент Database Engine синхронизирует одновременный доступ нескольких пользователей к одному фрагменту данных. Прежде чем транзакция сможет распоряжаться текущим состоянием фрагмента данных, например, для чтения или изменения данных, она должна защититься от изменений этих данных другой транзакцией. Для этого транзакция запрашивает блокировку фрагмента данных. Существует несколько режимов блокировки, например общая или монопольная. Режим блокировки определяет уровень подчинения данных транзакции. Ни одна транзакция не может получить блокировку, которая противоречит другой блокировке этих данных, предоставленной другой транзакции. Если транзакция запрашивает режим блокировки, противоречащий предоставленной ранее блокировке тех же данных, экземпляр компонента Database Engine приостанавливает ее работу до тех пор, пока первая блокировка не освободится.
При изменении фрагмента данных транзакция удерживает блокировку, защищая изменения до конца транзакции. Продолжительность блокировки, полученной для защиты операций чтения, зависит от уровня изоляции транзакции. Все блокировки, удерживаемые транзакц ией, освобождаются после ее завершения (при фиксации или откате). Приложения обычно не запрашивают блокировку напрямую. За управление блокировками отвечает внутренний компонент Database Engine, называемый диспетчером блокировок. Когда экземпляр компонента Database Engine обрабатывает инструкцию Transact SQL, обработчик запросов компонента Database Engine определяет, к каким ресурсам требуется доступ. Обработчик запросов определяет, какие типы блокировок требуются для защиты каждого ресурса, в зависимости от типа доступа и уровня изоляции транзакции. Затем обработчик запросов запрашивает соответствующую блокировку у диспетчера блокировок. Диспетчер блокировок предоставляет блокировку, если она не противоречит блокировкам, удерживаемым другими транзакциями. Использование блокировки как механизма управления транзакциями может разрешить проблемы параллелизма. Блокировка позволяет запускать все транзакции в полной изоляции друг от друга, что позволяет одновременно выполнять несколько транзакций. Уровень, на котором транзакция готова к принятию противоречивых данных, называется уровнем изоляции. Чем выше уровень изоляции, тем ниже вероятность непоследовательности данных, однако при этом появляется такой недостаток, как сокращение параллелизма. Каждая блокировка обладает тремя свойствами: гранулярностью (или размером блокировки), режимом (или типом блокировки) и продолжительностью.
Гранулярность блокировок и иерархии блокировок.
SQL Server поддерживает мультигранулярную блокировку, позволяющую транзакции блокировать
различные типы ресурсов. Чтобы уменьшить издержки применения блокировок, компонент Database Engine автоматически блокирует
ресурсы на соответствующем задаче уровне. Блокировка при меньшей гранулярности, например на уровне строк,
увеличивает параллелизм, но в то же время увеличивает и накладные расходы на обработку, поскольку при большом
количестве блокируемых строк требуется больше блокировок. Блокировки на большем уровне гранулярности, например
на уровне таблиц, обходится дорого в отношении параллелизма, поскольку блокировка целой таблицы ограничивает
доступ ко всем частям таблицы других транзакций. Однако накладные расходы в этом случае ниже, поскольку меньше
количество поддерживаемых блокировок. Компонент Database Engine часто получает блокировки на нескольких уровнях гранулярности одновременно, чтобы
полностью защитить ресурс. Такая группа блокировок на нескольких уровнях гранулярности называется иерархией
блокировки. Например, чтобы полностью защитить операцию чтения индекса, экземпляру компоненту Data base Engine
может потребоваться получить разделяемые блокировки на строки и намеренные разделяемые блокировки на страницы и
таблицу.
Эскалация блокировок
Эскалация (lock escalation) связана с тем, что по мере увеличения количества отдельных малых заблокированных объектов, накладные расходы, связанные с их поддержкой, начинают значительно сказываться на производительности. Блокировки длятся дольше, что приводит к спорным ситуациям чем дольше существует блокировка, тем выше вероятность обращения к заблокированному объекту со стороны другой транзакции. Очевидно, что на некотором этапе потребуется выполнить объединение (увеличение масштаба ) блокировок, чем собственно и занимается диспетчер блокировок. В инструкции ALTER TABLE предусмотрена опция вида SET LOCK ESCALATION = { AUTO | TABLE | DISABLE }), которая указывает разрешенные методы укрупнения блокировки для таблицы.