Simultaneidad de cursor (motor de base de datos)

Microsoft SQL Server admite cuatro opciones de simultaneidad en los cursores de servidor:

  • READ_ONLY

  • OPTIMISTIC WITH VALUES

  • OPTIMISTIC WITH ROW VERSIONING

  • SCROLL LOCKS

  • READ_ONLY
    No se permiten las actualizaciones posicionadas mediante el cursor y no se mantienen los bloqueos en las filas que forman el conjunto de resultados.

  • OPTIMISTIC WITH VALUES
    El control de simultaneidad optimista es una parte estándar de la teoría de control de transacciones. Esta simultaneidad se utiliza en situaciones en las que sólo existe una pequeña posibilidad de que otro usuario o proceso pueda actualizar una fila en el intervalo existente entre la apertura del cursor y la actualización de la fila. Cuando se abre un cursor con esta opción, no se mantienen los bloqueos en las filas subyacentes, lo que ayuda a maximizar el rendimiento. Si el usuario intenta modificar una fila, se comparan los valores actuales de la fila con los valores recuperados la última vez que ésta se recuperó. Si ha cambiado alguno de los valores, el servidor sabe que otro usuario o proceso ha actualizado la fila y devuelve un error. Si los valores son iguales, el servidor realiza la modificación.

    Seleccionar esta opción de simultaneidad obliga al usuario o programador a hacerse cargo del error ocasional que indica que otro usuario ha modificado la fila. Cuando una aplicación recibe este error, lo más habitual es que actualice el cursor, obtenga los nuevos valores y, a continuación, permita que el usuario decida si se lleva a cabo la modificación en los nuevos valores. Las columnas text, ntext e image no se utilizan en las comparaciones de simultaneidad en SQL Server 6.5 o versiones anteriores.

  • OPTIMISTIC WITH ROW VERSIONING
    Esta opción de simultaneidad optimista se basa en las versiones de las filas. Con las versiones de filas, la tabla subyacente debe tener un identificador de versión de algún tipo para que el servidor pueda determinar si se ha modificado la fila tras haberse leído en el cursor. En SQL Server, esta capacidad la proporciona el tipo de datos timestamp, que es un número binario que indica la secuencia relativa de modificaciones en una base de datos. Cada base de datos posee un valor actual global de marca de tiempo, **@@**DBTS. Cada vez que se modifica de algún modo una fila con una columna timestamp, SQL Server almacena el valor actual de **@@**DBTS en la columna timestamp y, a continuación, incrementa **@@**DBTS. Si una tabla contiene una columna timestamp, las marcas de tiempo se bajan al nivel de la fila. Así, el servidor puede comparar el valor actual de la marca de tiempo de una fila con el valor almacenado la última vez que dicha fila se recuperó, a fin de determinar si ha sido actualizada. No es preciso que el servidor compare los valores de todas las columnas, sino sólo la columna timestamp. Si una aplicación requiere simultaneidad optimista con versiones de filas en una tabla que no contiene ninguna columna timestamp, el cursor adopta de forma predeterminada el control de simultaneidad optimista basado en valores.

    Nota

    En los cursores que se abren en orígenes de datos remotos, las actualizaciones no se pueden efectuar mediante el cursor si el origen remoto no incluye una columna de marca de tiempo.

  • SCROLL LOCKS
    Esta opción implementa el control de simultaneidad pesimista, en el que la aplicación intenta bloquear las filas de la base de datos subyacente en el momento de importarlas al conjunto de resultados del cursor. Cuando se utilizan cursores de servidor, se coloca un bloqueo de actualización en la fila al leerla en el cursor. Si el cursor se abre en una transacción, los bloqueos de actualización de ésta se mantienen hasta que dicha transacción se confirma o se revierte; el bloqueo se quita cuando se recupera la siguiente fila. Si se ha abierto el cursor fuera de una transacción, el bloqueo se quita cuando se recupera la siguiente fila. Por consiguiente, se deberá abrir un cursor en una transacción siempre que el usuario desee tener un control de simultaneidad pesimista total. Un bloqueo de actualización impide que otra tarea adquiera un bloqueo exclusivo o de actualización y pueda, por lo tanto, actualizar la fila. Sin embargo, un bloqueo de actualización no bloquea un bloqueo compartido, por lo que no impide que otras tareas lean la fila, a menos que la segunda tarea también solicite una lectura con un bloqueo de actualización.

Bloqueos de desplazamiento

Estas opciones de simultaneidad de cursor pueden generar bloqueos de desplazamiento, dependiendo de las sugerencias de bloqueo que se hayan especificado en la instrucción SELECT de la definición de cursor. Los bloqueos de desplazamiento se adquieren en todas las filas de una recuperación y se mantienen hasta que se produce la siguiente recuperación o se cierra el cursor, lo que se produzca primero. En la siguiente recuperación, el servidor adquiere bloqueos de desplazamiento en las filas de la nueva recuperación y, a continuación, libera los bloqueos de desplazamiento de las filas recuperadas anteriormente. Los bloqueos de desplazamiento son independientes de los bloqueos de transacciones y pueden persistir tras haber realizado una operación de confirmación o de reversión. Si la opción de cerrar los cursores al confirmar está desactivada, la instrucción COMMIT no cierra los cursores abiertos y los bloqueos de desplazamiento se conservan después de confirmar a fin de mantener el aislamiento de los datos recuperados.

El tipo de los bloqueos de desplazamiento adquiridos depende de la opción de simultaneidad de cursor y de las sugerencias de bloqueo de la instrucción SELECT del cursor.

Nota

Los bloqueos de desplazamiento sólo se admiten en cursores dinámicos y controlados por conjunto de claves.

Sugerencias de bloqueo

Sólo lectura

Optimista con valores

Optimista con versiones de filas

Bloqueo

Sin sugerencias

-

-

-

Actualizar

NOLOCK*

-

-

-

-

HOLDLOCK

-

-

-

Actualizar

UPDLOCK

-

-

-

Actualizar

TABLOCKX

-

-

-

Actualizar

Todas las demás

-

-

-

Actualizar

*La especificación de la sugerencia NOLOCK hace que la tabla en la que se especifica sea de sólo lectura a través del cursor.

Especificar las opciones de simultaneidad de cursor

Las opciones de simultaneidad se especifican de forma diferente en cada entorno de cursor:

  • Cursores de Transact-SQL

    Especifique las palabras clave READ_ONLY, SCROLL_LOCK y OPTIMISTIC en la instrucción DECLARE CURSOR. La palabra clave OPTIMISTIC especifica simultaneidad optimista con versiones de filas. Los cursores de Transact-SQL no admiten la opción de simultaneidad optimista con valores.

  • Aplicaciones ADO

    Especifique adLockReadOnly, adLockPessimistic, adLockOptimistic o adLockBatchOptimistic en la propiedad LockType de un objeto Recordset.

  • Aplicaciones ODBC

    Establezca el atributo de la instrucción SQL_ATTR_CONCURRENCY en SQL_CONCUR_READ_ONLY, SQL_CONCUR_ROWVER, SQL_CONCUR_VALUES o SQL_CONCUR_LOCK.