Bloqueo de cursores
En SQL Server, la instrucción SELECT de una definición de cursor está sujeta a las mismas reglas de bloqueo de transacciones que se aplican a cualquier otra instrucción SELECT. Sin embargo, en los cursores se puede adquirir un conjunto adicional de bloqueos de desplazamiento en función del grado de simultaneidad de un cursor.
Los bloqueos de transacciones que adquiere una instrucción SELECT, incluyendo la instrucción SELECT de la definición de un cursor, se controlan mediante:
La configuración del nivel de aislamiento de transacción para la conexión.
Cualquier sugerencia de bloqueo especificada en la cláusula FROM.
Estos bloqueos se mantienen hasta el final de la transacción actual para los cursores y las instrucciones SELECT independientes. Cuando SQL Server se ejecuta en modo de confirmación automática, cada instrucción de SQL individual es una transacción y los bloqueos se liberan cuando termina la instrucción. Si SQL Server se ejecuta en el modo de transacciones explícitas o implícitas, se mantienen los bloqueos hasta que la transacción se confirma o revierte.
Por ejemplo, el bloqueo realizado en estos dos ejemplos de Transact-SQL es esencialmente el mismo:
/* Example 1 */
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRANSACTION
GO
SELECT * FROM AdventureWorks2008R2.Sales.Store;
GO
/* Example 2 */
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRANSACTION
GO
DECLARE abc CURSOR STATIC FOR
SELECT * FROM AdventureWorks2008R2.Sales.Store;
GO
OPEN abc
GO
Establecer el nivel de aislamiento de transacciones como lectura repetible significa que la instrucción SELECT independiente del ejemplo 1 y la instrucción SELECT que contiene DECLARE CURSOR en el ejemplo 2 generan bloqueos compartidos en cada fila que leen y que se mantienen los bloqueos compartidos hasta que la transacción se confirma o se revierte.
Adquirir bloqueos
Aunque los cursores obedecen las mismas reglas que las instrucciones SELECT independientes acerca del tipo de bloqueos de transacciones adquiridos, éstos se adquieren en momentos diferentes. Los bloqueos que genera una instrucción SELECT independiente o un cursor siempre se adquieren cuando se recupera una fila. En el caso de una instrucción SELECT independiente, todas las filas se recuperan cuando se ejecuta la instrucción. Sin embargo, cada tipo de cursor recupera las filas en un momento distinto:
Los cursores estáticos recuperan el conjunto de resultados completo cuando se abre el cursor. De esta manera, todas las filas del conjunto de resultados se bloquean en el momento de apertura.
Los cursores dinámicos recuperan las claves de cada fila del conjunto de resultados cuando se abre el cursor. De esta manera, todas las filas del conjunto de resultados se bloquean en el momento de apertura.
Los cursores dinámicos, incluidos los cursores normales de desplazamiento sólo hacia adelante, no recuperan las filas hasta que se capturan. Los bloqueos no se adquieren en estas filas hasta que se han recopilado.
Los cursores de desplazamiento sólo hacia delante se diferencian en que adquieren sus bloqueos dependiendo del plan de ejecución seleccionado por el optimizador de consultas. Si se selecciona un plan dinámico, no se adquieren bloqueos hasta que se recopilan las filas. Si se generan tablas de trabajo, las filas se importan a la tabla de trabajo y se bloquean en el momento de la apertura.
Los cursores también admiten sus propias especificaciones de simultaneidad, algunas de las cuales generan bloqueos adicionales en las filas con cada recopilación. Estos bloqueos de desplazamiento se mantienen hasta la siguiente operación de recopilación o hasta que se cierra el cursor, lo que se produzca primero. Si la opción de conexión para mantener cursores abiertos en una confirmación está activada, estos bloqueos se mantienen en las operaciones de confirmación o reversión.