Поделиться через


Блокировка курсора

В MicrosoftSQL Server инструкция SELECT в определении курсора подвержена тем же правилам блокировки транзакций, которые применяются для любой другой инструкции SELECT. Однако в курсорах возможны дополнительные блокировки прокрутки на основе спецификации уровня параллелизма курсоров.

На блокировки транзакций, приобретаемые любой инструкцией SELECT, которая входит в определение курсора влияет.

  • Уровень изоляции транзакции, устанавливаемый для соединения.

  • Любые подсказки блокировки, определенные в предложении FROM.

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

Например, блокировка, устанавливаемая в следующих двух примерах Transact-SQL по существу одинакова.

/* Example 1 */
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRANSACTION
GO
SELECT * FROM AdventureWorks.Sales.Store;
GO

/* Example 2 */
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRANSACTION
GO
DECLARE abc CURSOR STATIC FOR
SELECT * FROM AdventureWorks.Sales.Store;
GO
OPEN abc
GO

Установка уровня изоляции транзакций в операцию чтения с возможностью повторения означает, что обе независимые инструкции SELECT в примере 1 и инструкция SELECT, содержащаяся в инструкции DECLARE CURSOR в примере 2 формируют общие блокировки для каждой считываемой строки, а общие блокировки удерживаются до тех пор, пока транзакция не будет зафиксирована или не будет выполнен откат.

Запрос блокировок

Хотя курсоры подчиняются тем же правилам относительно типа получаемых блокировок, что и независимые инструкции SELECT, они получают блокировки в разные моменты времени. Блокировки, формируемые независимой инструкцией SELECT или курсором, всегда появляются при извлечении строки. Для независимой инструкции SELECT все строки получаются при выполнении инструкции. Однако курсоры получают строки в разные моменты времени, в зависимости от типа курсора.

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

  • Управляемые набором ключей курсоры получают ключи каждой строки результирующего набора во время открытия. Это приводит к блокировке каждой строки результирующего набора во время открытия.

  • Динамические курсоры (включая обычные однонаправленные курсоры) не получают строки, пока они не будут выбраны. Строки не запрашивают блокировку, пока они не будут выбраны.

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

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