Descripción de los niveles de aislamiento basado en el control de versiones de filas

El control de versiones de fila es un marco general de SQL Server que se utiliza para realizar las tareas siguientes:

  • Crear las tablas inserted y deleted en desencadenadores. Se crean versiones de las filas modificadas por el desencadenador. Esto incluye las filas modificadas por la instrucción que activó el desencadenador, así como las modificaciones de datos realizadas por el desencadenador.

  • Compatibilidad con los conjuntos de resultados activos múltiples (MARS). Si una sesión MARS emite una instrucción de modificación de datos (como INSERT, UPDATE o DELETE) en un momento en el que hay un conjunto de resultados activos, se crean versiones de las filas afectadas por la instrucción de modificación.

  • Compatibilidad con las operaciones de índice que especifican la opción ONLINE.

  • Compatibilidad con los niveles de aislamiento de transacción basado en el control de versionesde filas:

    • Nueva implementación del nivel de aislamiento de lectura confirmada que utiliza el control de versiones de filas para proporcionar una coherencia de lectura en las instrucciones.

    • Nuevo nivel de aislamiento de instantánea que proporciona una coherencia de lectura en las transacciones.

La base de datos tempdb debe tener espacio suficiente para el almacén de versiones. Cuando tempdb esté llena, las operaciones de actualización dejarán de generar versiones y se continuarán funcionando correctamente, pero es posible que las operaciones de lectura provoquen errores porque es necesaria una determinada versión de fila que ya no existe. Esto afecta a las operaciones como los desencadenadores, MARS y los índices en línea. Para obtener más información, vea Uso de recursos del control de versiones de filas.

La utilización del control de versiones de filas para las transacciones de lectura confirmada e instantáneas es un proceso de dos pasos:

  1. Seleccione el valor ON para una de las opciones de base de datos READ_COMMITTED_SNAPSHOT y ALLOW_SNAPSHOT_ISOLATION o para ambas.

  2. Seleccione el nivel de aislamiento de transacción apropiado en una aplicación:

    • Cuando el valor de la opción de base de datos READ_COMMITTED_SNAPSHOT sea ON, las transacciones que establezcan el nivel de aislamiento de lectura confirmada utilizarán el control de versiones de filas.

    • Cuando el valor de la opción de base de datos ALLOW_SNAPSHOT_ISOLATION sea ON, las transacciones podrán establecer el nivel de aislamiento de instantánea.

Cuando el valor de la opción de base de datos READ_COMMITTED_SNAPSHOT o ALLOW_SNAPSHOT_ISOLATION está establecido en ON, el SQL Server Database Engine (Motor de base de datos de SQL Server) asignará un número de secuencia de la transacción (XSN) a cada transacción que manipule datos que utilicen el control de versiones de filas. Las transacciones empiezan en el momento en que se ejecuta una instrucción BEGIN TRANSACTION. No obstante, el número de secuencia de la transacción empieza con la primera operación de lectura/escritura después de la instrucción BEGIN TRANSACTION. El número de secuencia de la transacción aumenta en incrementos de uno cada vez que se asigna.

Cuando el valor de las opciones de base de datos READ_COMMITTED_SNAPSHOT o ALLOW_SNAPSHOT_ISOLATION es ON, se mantienen las copias lógicas (versiones) para todas las modificaciones de datos realizadas en la base de datos. Cada vez que se modifica una fila mediante una transacción determinada, la instancia del Database Engine (Motor de base de datos) almacena una versión de la imagen previamente confirmada de la fila en tempdb. Cada versión se marca con el número de secuencia de la transacción que realizó el cambio. Las versiones de filas modificadas se encadenan mediante una lista de vínculos. El valor de fila más reciente se almacena siempre en la base de datos actual y se encadena a las filas de versiones almacenadas en tempdb.

[!NOTA]

En los casos de modificación de objetos grandes (LOB), sólo se copia el fragmento cambiado al almacén de versiones de tempdb.

El control de versiones de filas se conservan durante un tiempo suficiente para cumplir los requisitos de las transacciones ejecutadas con niveles de aislamiento basado en las versiones de filas. El Database Engine (Motor de base de datos) realiza un seguimiento del número de secuencia de la transacción útil más antiguo y elimina periódicamente todas las versiones de filas marcadas con números de secuencia de la transacción anteriores al número de secuencia útil más antiguo.

Cuando el valor de ambas opciones de base de datos es OFF, sólo se crean versiones de las filas modificadas por desencadenadores o sesiones MARS, o bien leídas por operaciones de índice ONLINE. Estas versiones de filas se liberan cuando dejan de ser necesarias. Un subproceso en segundo plano se ejecuta periódicamente para eliminar las versiones de filas obsoletas.

[!NOTA]

En el caso de las transacciones de ejecución breve, puede que se almacene en caché una versión de una fila modificada en el grupo de búferes sin que se escriba en los archivos de disco de la base de datos tempdb. Si la fila versionada no va a ser necesaria durante mucho tiempo, simplemente se eliminará del grupo de búferes y puede que no provoque una sobrecarga de E/S.

Comportamiento durante la lectura de datos

Cuando las transacciones que se ejecutan con niveles de aislamiento basado en el control de versiones de filas leen datos, las operaciones de lectura no adquieren bloqueos compartidos (S) para los datos que se leen, por lo que no bloquean las transacciones que están modificando datos. Asimismo, se minimiza la sobrecarga de los recursos de bloqueo, ya que se reduce el número de bloqueos adquiridos. El aislamiento de lectura confirmada mediante el control de versiones de filas y el aislamiento de instantánea están diseñados para proporcionar una coherencia de lectura de datos con versiones en las instrucciones o las transacciones.

Todas las consultas, incluidas las transacciones que se ejecutan en niveles de aislamiento basado en control de versiones de filas, adquieren bloqueos de estabilidad del esquema (Sch-S) durante la compilación y la ejecución. Debido a ello, las consultas se bloquean cuando una transacción simultánea aloja un bloqueo de modificación del esquema (Sch-M) en la tabla. Por ejemplo, una operación de lenguaje de definición de datos (DDL) adquiere un bloqueo Sch-M antes de modificar la información del esquema de la tabla. Las transacciones de consulta, incluidas las que se ejecutan en un nivel de aislamiento basado en el control de versiones de filas, se bloquean cuando se intenta adquirir un bloqueo Sch-S. Por el contrario, una consulta que aloja un bloqueo Sch-S bloquea una transacción simultánea que intenta adquirir un bloqueo Sch-M. Para obtener más información acerca del comportamiento de los bloqueos, vea Compatibilidad de bloqueos (motor de base de datos).

Cuando se inicia una transacción con el nivel de aislamiento de instantánea, la instancia del Database Engine (Motor de base de datos) registra todas las transacciones actualmente activas. Cuando la transacción de instantánea lee una fila que tiene una cadena de versiones, el Database Engine (Motor de base de datos) sigue la cadena y recupera la fila en la que el número de secuencia de la transacción cumple las condiciones siguientes:

  • Es el más cercano al número de secuencia de la transacción de instantánea que lee la fila, pero inferior al mismo.

  • No se encuentra en la lista de transacciones activas cuando se inició la transacción de instantánea.

Las operaciones de lectura realizadas por una transacción de instantánea recuperan la versión más reciente de cada fila confirmada en el momento en el que empezó la transacción de instantánea. De este modo se consigue una instantánea coherente con las transacciones de los datos tal como existían en el momento de inicio de la transacción.

Las transacciones de lectura confirmada que utilizan el control de versiones de filas funcionan de forma muy parecida. La diferencia es que las transacciones de lectura confirmada no utilizan su propio número de secuencia de la transacción cuando seleccionan versiones de filas. Cada vez que se inicia una instrucción, la transacción de lectura confirmada lee el número de secuencia de la transacción más reciente emitido para esa instancia del Database Engine (Motor de base de datos). Éste es el número de secuencia de la transacción utilizado para seleccionar las versiones de filas correctas para esa instrucción. Esto permite a las transacciones de lectura confirmada ver una instantánea de los datos tal como existían en el momento de inicio de cada instrucción.

[!NOTA]

Aunque las transacciones de lectura confirmada que utilizan el control de versiones de filas proporcionan una vista de los datos en el nivel de instrucciones coherente desde el punto de vista de las transacciones, las versiones de fila que se generan o a las que se tiene acceso con este tipo de transacción se mantienen hasta que la transacción finaliza.

Comportamiento durante la modificación de datos

En las transacciones de lectura confirmada que utilizan el control de versiones de filas, la selección de las filas que se deben actualizar se realiza mediante un recorrido de bloqueo en el que se obtiene un bloqueo de actualización (U) en la fila de datos cuando se leen los valores de datos. Es lo mismo que una transacción de lectura confirmada que no utiliza el control de versiones de filas. Si la fila de datos no cumple los criterios de actualización, se liberará el bloqueo de actualización en esa fila y se bloqueará y recorrerá la siguiente.

Las transacciones que se ejecutan con aislamiento de instantánea obtienen un enfoque optimista de la modificación de datos mediante la adquisición de bloqueos de datos antes de realizar la modificación sólo para forzar restricciones. De lo contrario, los bloqueos no se adquieren en los datos hasta que se van a modificar los datos. Cuando una fila de datos cumple los criterios de actualización, la transacción de instantánea comprueba que la fila de datos no haya sido modificada por una transacción simultánea confirmada antes de que empezara la transacción de instantánea. Si se ha modificado la fila de datos fuera de la transacción de instantánea, se producirá un conflicto de actualizaciones y se finalizará la transacción de instantánea. El Database Engine (Motor de base de datos) controla el conflicto de actualizaciones; no se puede deshabilitar su detección.

[!NOTA]

Las operaciones de actualización que se ejecutan con aislamiento de instantánea se ejecutan internamente con aislamiento de lectura confirmada cuando la transacción de instantánea tiene acceso a cualquiera de los elementos siguientes:

Una tabla con una restricción FOREIGN KEY.

Una tabla a la que se hace referencia en la restricción FOREIGN KEY de otra tabla.

Una vista indizada que hace referencia a más de una tabla.

No obstante, incluso en estas condiciones, la operación de actualización seguirá comprobando que los datos no hayan sido modificados por otra transacción. Si se han modificado, la transacción de instantánea detectará un conflicto de actualización y terminará.

Resumen del comportamiento

En la tabla siguiente se resumen las diferencias entre el aislamiento de instantánea y el aislamiento de lectura confirmada mediante el control de versiones de filas.

Propiedad

Nivel de aislamiento de lectura confirmada mediante el control de versiones de filas

Nivel de aislamiento de instantánea

La opción de base de datos cuyo valor debe ser ON para habilitar la compatibilidad necesaria.

READ_COMMITTED_SNAPSHOT

ALLOW_SNAPSHOT_ISOLATION

Forma en la que una sesión solicita el tipo específico de control de versiones de filas.

Utilice el nivel de aislamiento de lectura confirmada predeterminado o ejecute la instrucción SET TRANSACTION ISOLATION LEVEL para especificar el nivel de aislamiento READ COMMITTED. Se puede hacer una vez iniciada la transacción.

Requiere la ejecución de SET TRANSACTION ISOLATION LEVEL para especificar el nivel de aislamiento SNAPSHOT antes de que se inicie otra transacción.

La versión de los datos leídos por las instrucciones.

Todos los datos confirmados antes del inicio de cada instrucción.

Todos los datos confirmados antes del inicio de cada transacción.

Modo de control de las actualizaciones.

Vuelve desde las versiones de filas a los datos reales para seleccionar las filas que se actualizarán y utiliza bloqueos de actualización en las filas de datos seleccionadas. Adquiere bloqueos exclusivos en las filas de datos reales que se modificarán. Sin detección de conflictos de actualizaciones.

Utiliza las versiones de filas para seleccionar las filas que se actualizarán. Intenta adquirir un bloqueo exclusivo en la fila de datos real que se modificará y, si otra transacción ha modificado los datos, se producirá un conflicto de actualizaciones y se finalizará la transacción de instantánea.

Detección de conflictos de actualizaciones.

Ninguno.

Compatibilidad integrada. No se puede deshabilitar.