Usar niveles de aislamiento basado en versiones de filas

El marco de versiones de filas está siempre habilitado en MicrosoftSQL Server y lo utilizan varias características. Además de proporcionar niveles de aislamiento basados en versiones de filas, se utiliza para admitir las modificaciones efectuadas en desencadenadores y sesiones de conjuntos de resultados activos múltiples (MARS), así como para admitir lecturas de datos en operaciones de índice ONLINE.

Los niveles de aislamiento basados en versiones de filas se habilitan en la base de datos. Cualquier aplicación que tenga acceso a objetos de bases de datos habilitadas puede ejecutar consultas con los siguientes niveles de aislamiento:

  • Lectura de confirmadas, que utiliza versiones de filas al establecer la opción de base de datos READ_COMMITTED_SNAPSHOT en ON, como se muestra en el siguiente ejemplo de código:

    ALTER DATABASE AdventureWorks
        SET READ_COMMITTED_SNAPSHOT ON;
    

    Cuando la base de datos se habilita para READ_COMMITTED_SNAPSHOT, todas las consultas que se ejecutan en el nivel de aislamiento de lectura de confirmadas utilizan versiones de filas, lo que significa que las operaciones de lectura no bloquean las operaciones de actualización.

  • Puede habilitar el aislamiento de instantáneas configurando la opción de base de datos ALLOW_SNAPSHOT_ISOLATION en ON, como se muestra en el ejemplo de código siguiente:

    ALTER DATABASE AdventureWorks
        SET ALLOW_SNAPSHOT_ISOLATION ON;
    

    Una transacción que se ejecute en aislamiento de instantánea puede tener acceso a tablas de la base de datos que se hayan habilitado para instantáneas. Para obtener acceso a tablas que no se han habilitado para instantáneas, debe cambiarse el nivel de aislamiento. El siguiente ejemplo de código muestra una instrucción SELECT que une dos tablas mientras se ejecuta en una transacción de instantáneas. Una tabla pertenece a una base de datos en la que no se habilitó el aislamiento de instantánea. Cuando la instrucción SELECT se ejecuta en aislamiento de instantánea, no lo hace correctamente.

    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;
    

    El siguiente ejemplo de código muestra la misma instrucción SELECT modificada para cambiar el nivel de aislamiento de la transacción a lectura de confirmadas. Gracias a este cambio, la instrucción SELECT se ejecuta correctamente.

    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;
    

Para obtener más información acerca de la configuración del nivel de aislamiento en una aplicación, vea Ajustar los niveles de aislamiento de transacción.

Limitaciones de transacciones con niveles de aislamiento basados en versiones de filas

Tenga en cuenta las siguientes limitaciones cuando trabaje con niveles de aislamiento basados en versiones de filas:

  • No se puede habilitar READ_COMMITTED_SNAPSHOT en tempdb, msdb ni master.

  • Las tablas temporales globales se almacenan en tempdb. Al tener acceso a tablas temporales globales en una transacción de instantáneas, debe realizarse alguna de las siguientes acciones:

    • Establecer la opción de base de datos ALLOW_SNAPSHOT_ISOLATION como ON en tempdb.

    • Usar una sugerencia de aislamiento para cambiar el nivel de aislamiento de la instrucción.

  • Las transacciones de instantáneas provocan errores cuando:

    • Una base de datos pasa a ser de sólo lectura una vez iniciada la transacción de instantáneas, pero antes de que ésta obtenga acceso a la base de datos.

    • Si al tener acceso a objetos de varias bases de datos, el estado de una base de datos se modificó de forma que la recuperación de la base de datos se produjo después del inicio de la transacción, pero antes del acceso de la transacción de instantáneas a la base de datos. Por ejemplo, la base de datos se estableció en OFFLINE y luego en ONLINE, cierre automático y apertura de base de datos, o adjuntar y separar una base de datos.

  • Las transacciones distribuidas, incluidas las consultas de bases de datos con particiones distribuidas, no se admiten en aislamiento de instantánea.

  • SQL Server no mantiene varias versiones de los metadatos del sistema. Las instrucciones del lenguaje de definición de datos (DDL) de tablas y otros objetos de base de datos (índices, vistas, tipos de datos, procedimientos almacenados y funciones de CLR (Common Language Runtime)) cambian los metadatos. Si una instrucción DDL modifica un objeto, cualquier referencia simultánea al objeto en aislamiento de instantánea provoca errores en la transacción de instantáneas. Las transacciones de lectura de confirmadas no tienen esta limitación cuando la opción de base de datos READ_COMMITTED_SNAPSHOT es ON.

    Por ejemplo, el administrador de la base de datos ejecuta la siguiente instrucción ALTER INDEX.

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

    Cualquier transacción de instantáneas que esté activa cuando se ejecuta la instrucción ALTER INDEX recibirá un error si intenta hacer referencia a la tabla HumanResources.Employee una vez ejecutada la instrucción ALTER INDEX. Las transacciones de lectura de confirmadas que utilicen versiones de filas no se ven afectadas.

    [!NOTA]

    Las operaciones BULK INSERT pueden provocar cambios en los metadatos de la tabla de destino (por ejemplo, al deshabilitar las comprobaciones de restricciones). Cuando esto sucede, las transacciones simultáneas de aislamiento de instantánea que obtengan acceso a tablas de inserciones masivas generarán un error.