Compartir a través de


Transacciones en tablas de Memory-Optimized

El control de versiones de fila en tablas basadas en disco (mediante el aislamiento SNAPSHOT o READ_COMMITTED_SNAPSHOT) proporciona una forma de control de simultaneidad optimista. Los lectores y escritores no se bloquean entre sí. Con las tablas optimizadas para memoria, los escribientes no bloquean a otros escribientes. Con el control de versiones de fila en tablas basadas en disco, una transacción bloquea la fila y las transacciones simultáneas que intentan actualizar la fila están bloqueadas. No hay ningún bloqueo con tablas optimizadas para memoria. En su lugar, si dos transacciones intentan actualizar la misma fila, se producirá un conflicto de escritura y escritura (error 41302).

A diferencia de las tablas que utilizan discos, las tablas optimizadas para memoria permiten un control de concurrencia optimista con los niveles de aislamiento más altos, como son REPEATABLE READ y SERIALIZABLE. No se toman bloqueos para aplicar los niveles de aislamiento. En su lugar, al final de la validación de transacciones se garantiza la lectura repetible o las suposiciones de serialización. Si se infringen las suposiciones, se finaliza la transacción. Para obtener más información, consulte Niveles de aislamiento de transacciones.

La semántica de transacciones importante para las tablas optimizadas para memoria son:

  • Versionado múltiple

  • Aislamiento de transacciones basado en instantáneas

  • Optimista

  • Detección de conflictos

Cada una de estas semánticas se explica en las secciones siguientes.

Versionamiento múltiple en las tablas Memory-Optimized

Las filas de las tablas optimizadas para memoria pueden tener versiones diferentes. Las transacciones simultáneas tienen acceso a versiones potencialmente diferentes de la misma fila.

Los datos de tabla optimizados para memoria están basados en versiones. Para cualquier fila puede haber versiones de fila diferentes que sean válidas en distintos momentos en el tiempo. Las tablas basadas en disco mantienen versiones de fila diferentes cuando READ_COMMITTED_SNAPSHOT o ALLOW_SNAPSHOT_ISOLATION está activado. Las tablas optimizadas para memoria mantienen versiones de fila diferentes, incluso si READ_COMMITTED_SNAPSHOT y ALLOW_SNAPSHOT_ISOLATION están desactivadas. Las versiones de fila de las tablas optimizadas para memoria no se mantienen en tempdb. En su lugar, las versiones de fila se mantienen en línea, como parte de las estructuras de datos optimizadas para memoria que almacenan las filas en memoria.

Snapshot-Based Aislamiento de transacciones para tablas de Memory-Optimized

Todas las operaciones de una sola transacción usan la misma instantánea transaccionalmente coherente de las tablas optimizadas para memoria. Todo el aislamiento de transacciones para tablas optimizadas para memoria se basa en instantáneas. Por ejemplo, una transacción que utiliza el nivel de aislamiento serializable para acceder a las tablas optimizadas para memoria realiza todas las operaciones en la misma instantánea transaccionalmente coherente.

Las transacciones que acceden a tablas optimizadas para memoria utilizan este versionado de filas para obtener una instantánea coherente a nivel transaccional de las filas de las tablas. Los datos leídos por cualquier instrucción de la transacción serán la versión transaccionalmente coherente de los datos que existían en el momento en que se inició la transacción. Por lo tanto, las modificaciones realizadas por transacciones que se ejecutan simultáneamente no son visibles para las instrucciones de la transacción actual.

Control optimista de concurrencia para tablas de Memory-Optimized

Los conflictos y fallos son poco frecuentes, y las transacciones en tablas optimizadas para el uso de memoria asumen que no hay conflictos con transacciones concurrentes y las operaciones se completan con éxito. Las transacciones no toman bloqueos ni cierres en la tabla optimizada para memoria para garantizar el aislamiento de la transacción. Los escritores no bloquean a los lectores. Los escritores no obstaculizan a otros escritores. En su lugar, las transacciones continúan bajo la suposición (optimista) de que no habrá conflictos con otras transacciones. No usar bloqueos y bloqueos temporales y no esperar a que otras transacciones terminen de procesar las mismas filas mejora el rendimiento.

Además, si una transacción (TxA) lee las filas insertadas o modificadas por otra transacción (TxB) que está en proceso de confirmación, se asume optimistamente que la otra transacción se confirmará en lugar de esperar a que se produzca la confirmación. En este caso, la transacción TxA establecerá una dependencia de confirmación en la transacción TxB.

Detección de conflictos, validación y comprobaciones de dependencias para confirmación

SQL Server detecta conflictos entre transacciones simultáneas, así como infracciones de nivel de aislamiento y condenará una de las transacciones en conflicto. Esta transacción deberá reintentarse. (Para obtener más información, vea Directrices para la lógica de reintento para transacciones en tablas de Memory-Optimized).

El sistema asume optimistamente que no hay conflictos y ninguna infracción del aislamiento de transacciones. Si se producen conflictos que puedan provocar incoherencias en la base de datos o que puedan infringir el aislamiento de transacciones, se detectan estos conflictos y se finaliza la transacción.

Si se detecta un conflicto, la transacción se finaliza y el cliente debe reintentar.

En la tabla siguiente se resumen las condiciones de error de las transacciones que acceden a las tablas optimizadas para memoria.

Condiciones de error para las transacciones que acceden a tablas optimizadas para memoria.

Error Escenario
Conflicto de escritura. Intentar actualizar un registro que se ha actualizado desde que se inició la transacción. ACTUALIZAR o ELIMINAR una fila que ha sido actualizada o eliminada por una transacción concurrente.
Error de validación de lectura repetible. Una fila que fue leída por la transacción ha sido cambiada (actualizada o eliminada) desde que se inició la transacción. Normalmente, la validación de lectura repetible se produce cuando se usan niveles de aislamiento de transacciones REPEATABLE READ y SERIALIZABLE.
Error de validación serializable. Se ha insertado una nueva fila (fantasma) en uno de los rangos de escaneo de la transacción desde que comenzó la transacción. La fila habría sido visible para la transacción si la fila se hubiera confirmado en la base de datos antes de que se iniciara la transacción. La validación SERIALIZABLE típicamente ocurre cuando se usa el aislamiento SERIALIZABLE y se validan las restricciones de clave primaria.
Error de confirmación de dependencia. La transacción dependía de otra transacción que no se pudo confirmar, ya sea debido a uno de los errores de esta tabla, una condición de falta de memoria o debido a errores de confirmación en el registro de transacciones. Este error puede producirse tanto con transacciones de lectura y escritura como de solo lectura.

Duración de la transacción

Los errores mencionados en la tabla anterior pueden producirse en distintos puntos durante una transacción. En la ilustración siguiente se muestran las fases de una transacción que accede a tablas optimizadas para memoria.

Duración de una transacción. Duración de una transacción que accede a tablas optimizadas para memoria.

Procesamiento normal

Durante esta fase, se ejecutan las instrucciones Transact-SQL emitidas por el usuario. Las filas se leen de las tablas y las versiones nuevas se registran en la base de datos. La transacción está aislada de todas las demás transacciones simultáneas. La transacción usa la instantánea de las tablas optimizadas para memoria que existe al inicio de la transacción.

Las escrituras en las tablas de esta fase de la transacción aún no son visibles para otras transacciones, con una excepción: las actualizaciones y eliminaciones de filas son visibles para actualizar y eliminar operaciones en otras transacciones, con el fin de detectar conflictos de escritura.

Si una operación de actualización o eliminación ve que se ha actualizado o eliminado una fila desde el inicio lógico de la transacción, se producirá un error 41302. El mensaje del error 41302 es "La transacción actual intentó actualizar un registro en la tabla X que se ha actualizado desde que se inició esta transacción. Se anuló la transacción".

Este error condena la transacción (incluso si XACT_ABORT está desactivada), lo que significa que la transacción se revertirá cuando finalice la sesión del usuario. Las transacciones condenadas no se pueden confirmar y solo permiten operaciones de lectura que no escriben en el registro de transacciones ni acceden a tablas optimizadas para memoria.

Confirmar dependencias

Durante el procesamiento normal, una transacción puede leer filas escritas por otras transacciones que se encuentran en la fase de validación o confirmación, pero que aún no se han confirmado. Las filas son visibles porque la hora de finalización lógica de las transacciones se ha asignado al inicio de la fase de validación.

Si una transacción lee estas filas no confirmadas, tomará una dependencia de confirmación en esa transacción. Esto tiene dos implicaciones principales:

  • Una transacción no puede confirmarse hasta que las transacciones de las que depende se hayan confirmado. En otras palabras, no puede entrar en la fase de confirmación hasta que todas las dependencias se hayan resuelto.

  • Además, los conjuntos de resultados no se devuelven al cliente hasta que se hayan borrado todas las dependencias. Esto impide que el cliente observe datos no confirmados.

Si alguna de las transacciones dependientes no se puede confirmar, se produce un error de dependencia de confirmación. Esto significa que la transacción no se podrá confirmar debido al error 41301 ("Una transacción anterior de la cual la transacción actual dependía ha sido abortada, y la transacción actual ya no se puede confirmar").

Fase de validación

Durante la fase de validación, el sistema valida que las suposiciones necesarias para el nivel de aislamiento de transacción solicitado eran verdaderas entre el inicio lógico y el final lógico de la transacción.

Al principio de la fase de validación, a la transacción se le asigna una hora de finalización lógica. Las versiones de fila escritas en la base de datos se vuelven visibles para otras transacciones en el momento lógico de finalización. Para obtener más información, vea Confirmar dependencias.

Validación de lectura repetible

Si el nivel de aislamiento de la transacción es REPEATABLE READ o SERIALIZABLE, o si se tiene acceso a tablas bajo el aislamiento REPEATABLE READ o SERIALIZABLE (para obtener más información, vea la sección aislamiento de operaciones individuales en niveles de aislamiento de transacciones), el sistema valida que las lecturas son repetibles. Esto significa que valida que las versiones de las filas leídas por la transacción siguen siendo versiones de fila válidas en la hora de finalización lógica de la transacción.

Si alguna de las filas se ha actualizado o cambiado, la transacción no se puede confirmar con el error 41305 ("No se pudo confirmar la transacción actual debido a un error de validación de lectura repetible).

Este error también puede producirse si se quita una tabla después de una operación de inserción, actualización o eliminación y antes de que se confirme la transacción. Esto solo se aplica a las operaciones de inserción, actualización o eliminación en procedimientos almacenados compilados de forma nativa. Estas operaciones de escritura realizadas a través de Transact-SQL interpretado hacen que la instrucción DROP TABLE bloquee y espere hasta que se confirme la transacción.

Validación serializable

La validación serializable se realiza en dos casos:

  • Si el nivel de aislamiento de la transacción es SERIALIZABLE o se accede a las tablas bajo el aislamiento SERIALIZABLE.

  • Si las filas se insertan en un índice único, como el índice creado para una restricción de clave primaria. El sistema valida que no se han insertado simultáneamente filas con la misma clave.

El sistema valida que no se han escrito filas fantasma en la base de datos. Las operaciones de lectura realizadas por la transacción se evalúan para determinar que no se insertaron nuevas filas en los intervalos de examen de estas operaciones de lectura.

La inserción de una clave en un índice único incluye una operación de lectura implícita para determinar que la clave no es un duplicado. La validación serializable para índices únicos garantiza que estos índices no pueden tener duplicados en caso de que dos transacciones inserte simultáneamente la misma clave.

Si se detectan filas fantasma, la transacción no se puede confirmar con el error 41325 ("No se pudo confirmar la transacción actual debido a un error de validación serializable").

Procesamiento de confirmaciones

Si la validación se realiza correctamente y se borran todas las dependencias de transacción, la transacción entra en la fase de procesamiento de confirmación. Durante esta fase, los cambios en las tablas duraderas se escriben en el registro y el registro se escribe en el disco para garantizar la durabilidad. Una vez que el registro de la transacción se ha escrito en el disco, el control se devuelve al cliente.

Todas las dependencias de confirmación de esta transacción se borran y todas las transacciones que han estado esperando a que se confirme esta transacción pueden continuar.

Limitaciones

  • No se admiten transacciones entre bases de datos con tablas optimizadas para memoria. Todas las transacciones que acceden a tablas optimizadas para memoria no pueden acceder a más de una base de datos, con la excepción del acceso de lectura y escritura a tempdb y el acceso de solo lectura a la base de datos maestra del sistema.

  • Las transacciones distribuidas no se admiten con tablas optimizadas para memoria. Las transacciones distribuidas iniciadas con BEGIN DISTRIBUTED TRANSACTION no pueden tener acceso a las tablas optimizadas para memoria.

  • Las tablas optimizadas para memoria no admiten el bloqueo. No se admiten bloqueos explícitos mediante sugerencias de bloqueo (como TABLOCK, XLOCK, ROWLOCK) con tablas optimizadas para memoria.

Véase también

Descripción de transacciones en tablas de Memory-Optimized