Использование уровней изоляции строк на основе управления версиями

Платформа управления версиями строк в SQL Server всегда включена и используется многими функциями. Помимо уровней изоляции, основанных на управлении версиями строк, эта структура используется для поддержки изменений в триггерах и сеансах MARS, а также для поддержки считывания данных операциями индекса ONLINE.

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

  • Изоляция зафиксированного считывания использует управление версиями строк, присваивая параметру базы данных READ_COMMITTED_SNAPSHOT значение ON, как показано в следующем примере кода:

    ALTER DATABASE AdventureWorks2008R2
        SET READ_COMMITTED_SNAPSHOT ON;
    

    Если в базе данных задан параметр READ_COMMITTED_SNAPSHOT, то все запросы, которые выполняются на уровне изоляции read committed, применяют управление версиями строк, то есть операции считывания не блокируют операции обновления.

  • Изоляция моментальных снимков с помощью присвоения параметру базы данных ALLOW_SNAPSHOT_ISOLATION значения ON, как показано в следующем примере кода:

    ALTER DATABASE AdventureWorks2008R2
        SET ALLOW_SNAPSHOT_ISOLATION ON;
    

    Транзакция, запускаемая при изоляции моментальных снимков, может обращаться к таблицам в базе данных, которые были включены для моментального снимка. Чтобы получить доступ к остальным таблицам, следует изменить уровень изоляции. Например, в следующем примере кода показана инструкция SELECT, которая во время выполнения транзакции моментального снимка соединяет две таблицы. Одна таблица принадлежит базе данных с выключенной изоляцией моментальных снимков. Если инструкция SELECT запускается при включенной изоляции моментальных снимков, она завершается неуспешно.

    SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
    BEGIN TRAN
        SELECT t1.col5, t2.col5
            FROM Table1 as t1
            INNER JOIN SecondDB.dbo.Table2 as t2
                ON t1.col1 = t2.col2;
    

    В следующем примере кода показана измененная инструкция SELECT, в которой уровень изоляции транзакций изменен на зафиксированное считывание. Благодаря этому инструкция SELECT выполняется успешно.

    SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
    BEGIN TRAN
        SELECT t1.col5, t2.col5
            FROM Table1 as t1
            WITH (READCOMMITTED)
            INNER JOIN SecondDB.dbo.Table2 as t2
                ON t1.col1 = t2.col2;
    

Дополнительные сведения о настройке уровня изоляции в приложении см. в разделе Настройка уровней изоляции транзакций.

Ограничения транзакций, использующих уровни изоляции строк на основе управления версиями

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

  • Параметр READ_COMMITTED_SNAPSHOT должен быть выключен в базах данных tempdb, msdb и master.

  • Глобальные временные таблицы хранятся в базе данных tempdb. При обращении к глобальным временным таблицам внутри транзакции моментального снимка необходимо выполнить одно из следующих действий:

    • Присвойте значение ON параметру ALLOW_SNAPSHOT_ISOLATION в базе данных tempdb.

    • Чтобы изменить уровень изоляции для инструкции, ознакомьтесь с соответствующими подсказками.

  • Транзакции моментальных снимков завершаются неуспешно в следующих случаях:

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

    • Если при обращении к объектам из нескольких баз данных состояние базы данных изменилось следующим образом: она была восстановлена после запуска транзакции моментального снимка, но до того, как эта транзакция получила доступ к базе данных. Например: база данных перешла в состояние OFFLINE, затем в ONLINE, автоматически закрылась, затем открылась, или была отсоединена, а затем присоединена.

  • Распределенные транзакции (включая запросы к распределенным секционированным базам данных) не поддерживаются при изоляции моментальных снимков.

  • SQL Server не сохраняет несколько версий системных метаданных. Метаданные изменяются с помощью инструкций языка DDL, применяемых к таблицам и другим объектам баз данных (индексам, представлениям, типам данных, хранимым процедурам и функциям среды CRL). Если инструкция DDL изменяет объект, то при изоляции моментальных снимков любая параллельная ссылка на объект вызовет сбой транзакции. Это ограничение не затрагивает участвующие в считывании транзакции, если включен параметр базы данных READ_COMMITTED_SNAPSHOT.

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

    USE AdventureWorks2008R2;
    GO
    ALTER INDEX AK_Employee_LoginID
        ON HumanResources.Employee REBUILD;
    GO
    

    При попытке вызвать таблицу HumanResources.Employee во время выполнения инструкции ALTER INDEX все активные транзакции моментальных снимков получат сообщение об ошибке после завершения выполнения инструкции ALTER INDEX. Это не относится к участвующим в считывании транзакциям, которые применяют управление версиями строк.

    ПримечаниеПримечание

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