Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие.doc
Скачиваний:
57
Добавлен:
14.05.2015
Размер:
1.51 Mб
Скачать

2. Базовая информация о блокировках. Типы блокировок

Целостность данных при транзакциях в SQL Server под­держивается специальным механизмом блокировок, который управляется диспетчером блокировок. Он отключает управление транзакциями только тогда, когда база данных переводится в режим "только для чтения" и однопользовательский.

При обработке данных система обращается к различным ресурсам, причем доступ к ресурсу процесс получает в два этапа:

  • выполняется запрос на требуемую блокировку

  • если это, возможно, доступ предоставляется, а если нет, то процесс ждет, пока это станет возможным, т.е. блоки­руется.

Продолжительность ожидания зависит от многих факто­ров, но, в принципе, это время конечно. Однако может возник­нуть такая ситуация, когда ожидание вообще не может быть прекращено (два процесса взаимно блокируют друг друга). Это так называемая тупиковая ситуация (deadlock). В SQL Server реализованы эффективные средства обнаружения и прерывания таких ситуаций.

Блокировки различаются по уровням. В SQL Sever ис­пользуются следующие уровни блокировки:

  • RID (идентификатор строки) — используется для блоки­ровки отдельной строки внутри таблицы.

  • Key (ключ) — используется для блокировки внутри ин­декса для защиты диапазона ключей в последовательных транзакциях.

  • Page (страница) — используется для блокировки 8 Кб страниц данных или индексов.

  • Extent (экстент) — используется для блокировки группы из 8 страниц данных или индексов.

  • Table (таблица) — используется для блокировки таблиц, включая данные и индексы.

  • DB (база данных) — используется для блокировки на уровне базы данных

Блокировка на уровне записей устанавливается для отдель­ных таблиц системной хранимой процедурой sp_TABLEOPTION и применяется только для операций вставки. Этот уровень бло­кировки используется редко.

Внутренним рабочим блоком данных в SQL Server является страница размером 8 Кб, поэтому все, что выполняется серве­ром, должно выполняться над объемом данных не менее 8 Кб.

Один из важных принципов написания многопользователь­ских приложений заключается в необходимости обеспечить спо­соб одновременной и независимой работы нескольких пользова­телей. Чем больше возможности манипулирования с данными в одной и той же таблице без влияния пользователей друг на друга (из-за блокировок), тем выше конкурентоспособность приложения и выше шанс, что это приложение сможет поддер­живать работу большого количества пользователей. Таблицы, обращение к которым происходит достаточно часто, например таблицы уникальных общесистемных значений, должны обеспечивать в максимальной степени параллельный доступ, чтобы этого добиться, необходимо располагать на одной странице данных как можно меньше строк таблицы, и тем са­мым ограничить количество непреднамеренных блокировок строк в результате действия пользователя. Кроме этого, для таких таблиц необходимо минимизировать продолжительность пользовательских транзакций.

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

Табличная блокировка (table lock) имеет место, когда пользователь выполняет запрос на обновление таблицы без предложения WHERE, что подразумевает обновление всех строк таблицы. Кроме этого, табличная блокировка может происходить в случае, когда число страниц блокируемых данных превышает так называемый порог распространения блокировки (lock escalation threshold), определенный для данной таблицы или базы данных.

Расширенная блокировка (extent lock) имеет место, когда система SQL Server для выполнения пользовательского запроса вынуждена расширить базу данных на 8 новых страниц.

SQL Server может размещать на страницах баз данных и в таблицах блокировки нескольких типов. Для страниц возможны следующие блокировки: разделяемая (ключевое слово SHARED, монопольная (ключевое слово EXCLUSIVE) и блокировка обновления (ключевое слово UPDATE). Разделяемая блокировка позволяет другим процессам иметь блокировки на одной и той же странице, а монопольная - нет.

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

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

Блокировка обновления — это нечто среднее между разделяемой и монопольной блокировками. При блокировке этого типа процессу разрешается иметь на странице разделяемую блокировку, но только до тех пор, пока на ней не происходит обновление данных. Блокировки обновления выполняются при построении курсора на сервере. Такие блокировки автоматически становятся монопольными, когда на одной из ассоциированной с курсором страниц происходит обновление. На уровне таблицы разделяемая и монопольная блокировки работают так же, как и на уровне страницы.

Кроме основных, SQL Server использует специальные типы блокировок, перечисленные ниже.

Блокировки намерения (intent lock) - показывают, что в таблице имеется несколько страниц, которые SQL Server в ответ на запрос пользовательского процесса намеревается блокировать на уровне страницы. Блокировка такого типа задается в запросе, если он выполняется перед другим запросом, который заблокирует страницы в таблице. В SQL Server 2000 три вида блокировок намерения:

  • Разделяемые (intent shared) - к ресурсам, расположенным ниже по иерархии, выполняется доступ на чтение;

  • Монопольные (intent exclusive) — к ресурсам, расположенным ниже по иерархии, выполняется доступ на изменение;

  • Разделяемые монопольные (shared with intent exclusive) - намерение в транзакции разрешить доступ на чтение к ресурсу, который находится выше по иерархии, и на модификацию ресурсов на более низком уровне иерархии.

В таблице 14 описаны совместимость различных типов блокировок.

Таблица 14

Запрашиваемая блокировка

Наложенная блокировка

S

U

X

IS

IX

SIX

Разделяемая (S)

*

*

*

Обновления (U)

*

*

Монопольная (X)

Намерения (IX)

*

*

*

*

*

Намерения монопольная (IX)

*

*

Намерения разделяемая монопольная (SIX)

*

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

Кроме названных, в версии 2000 появились два новых типа блокировок: блокировка схемы (schema lock) и блокировка диапазонов ключей (Key - range locking). Под "схемой" понимается текущее определение объекта (таблицы, представления и т. п.). Блокировки этого типа обеспечивают возможность динамической перестройки структуры таблицы. При компиляции и выполнении запроса структура таблицы блокируется именно с помощью блокировки схемы, которая существует в двух видах:

  • Блокировка постоянства схемы (schema stability) - используется при любом обращении к таблице для запрещения изменения ее структуры; этот тип блокировки совместим с любым другим, за исключением блокировки изменения схемы.

  • Блокировка изменения схемы (schema modification) - используется при изменении структуры таблицы для запрещения любых операций обращения к ней; несовместим со всеми другими блокировками.

Блокировка диапазонов ключей обеспечивает последовательность транзакций (выполнение транзакций в режиме SERIALIZABLE) при расщеплении страниц. При этом режиме необходимо препятствовать выполнению операций вставки, удаления и обновления записей в диапазоне ключей, удовлетворяющих определенным условиям. Для этого сервер блокирует запись на индексные страницы. Этот тип блокировки состоит из двух компонентов: диапазона ключей и записей.

При написании многопользовательских приложений для баз данных, можно выбрать один из двух подходов к управлению транзакциями: оптимистическую или пессимистическую блокировку. При оптимистической блокировке (optimistic locking) предполагается, что при разработке приложения вы придаете значение только его логике и явно не управляете блокировкой записей, возлагая решение этой задачи на систему управления базами данных. При пессимистической блокировке (pessimistic locking) предполагается, что определенный тип механизма блокировки реализован в самом приложении.

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

  • Минимизируйте время, которое транзакция находится в открытом состоянии. Это делается ограничением размера кода SQL между инструкциями BEGIN TRAN и COMMIT TRAN.

  • Стройте код приложения так, чтобы гарантировать блокировку нужной записи, и не оставляйте блокировки на время простого просмотра данных.

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

В SQL Server при запросах к базе данных можно по-разному реализовать задание и отмену блокировок. Один из способов предполагает установку уровня изолированности (isolation level) транзакций. В SQL Server имеется три различных уровня изолированности: завершенное чтение (read committed), незавершенное чтение (read uncommitted), повторяемое чтение (repeatable read).

Завершенное чтение (read committed) — это метод выполнения операций, установленный в SQL Server по умолчанию. Он не позволяет считывать "грязные" (dirty) или незавершенные данные из базы данных.

Для установки уровня изолированности read committed служит инструкция:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

Незавершенное чтение (read uncommitted) обеспечивает выполнение тех же функций, что и ключевое слово NOLOCK в отдельной инструкции SELECT. Никакие разделяемые блокировки данных, если они имеются в запросе, не выполняются. Кроме этого, не выполняются никакие блокировки, установленные другими пользователями.

Инструкция для установки уровня изолированности read uncommitted:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Повторяемое чтение (repeatable read) — это наиболее монопольный тип блокировки, поддерживаемый в SQL Server. Повторяемое чтение гарантирует неизменность читаемых вами данных и невозможность влияния на ваши данные со стороны любой выполняемой другим пользователем транзакции в течение времени жизни вашей транзакции. Из-за того что повторяемое чтение явно блокирует доступ к данным других пользователей, этот вид уровня изолированности снижает возможности параллельного доступа и, соответственно, снижает число пользователей, которые могут одновременно получить доступ к данным без влияния друг на друга.

Инструкция для установки уровня изолированности repeatable read:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ