Comportamiento del cursor en el contexto de una conexión

Cursor de lectura general en conflictos de grabación procedentes de otro descriptor de sentencia

Una aplicación puede tener varios descriptores de sentencia que efectúen operaciones de lectura y grabación en la misma tabla al mismo tiempo. Los conflictos se producen cuando un descriptor está efectuando una operación de grabación en la tabla (por ejemplo, UPDATE, DELETE o INSERT) al tiempo que otro descriptor está en medio de una operación de lectura o grabación. En DB2 Everyplace el cursor de lectura es estable y está siempre leyendo los datos más actuales. Sobrevive a los conflictos de grabación, sin tener en cuenta si está utilizando o no un índice. Por ejemplo, suponga que una aplicación tiene dos descriptores de sentencia. El descriptor número 1 se utiliza para buscar filas de una tabla T, en tanto que el descriptor número 2 se utiliza para suprimir algunas filas de la misma tabla. Es probable que cada descriptor se haya creado por medio de hebras diferentes (por ejemplo, en un entorno de hebra de Java).

A continuación se muestra un escenario posible:

// Buscar 2 filas en la tabla T
   Statement handle 1: execute "SELECT A FROM T WHERE primary_key < 10"
   Statement handle 1: fetch one row; fetch another row
    // Suprimir algunas filas de la tabla T
   Statement handle 2: prepare "DELETE FROM T WHERE primary_key = ?"
   Statement handle 2: execute
    // Seguir buscando una fila más en T
   Statement handle 1: fetch one row 

En este punto de la ejecución, el descriptor de sentencia número 1 podrá seguir buscando la fila siguiente (si existe), sin tener en cuenta si se utiliza o no un índice. En el escenario anterior, se utiliza un índice debido a que hay una clave primaria. La idea es que DB2 Everyplace intentará volver a situar la posición del cursor del descriptor número 1, utilizando su posición actual, antes de avanzar. Si la posición actual ya no existe (por ejemplo, otro descriptor de sentencia suprimió la fila), el cursor simplemente avanza hacia la posición siguiente efectuando una búsqueda. Del mismo modo, si otro descriptor de sentencia ha suprimido la posición siguiente, el cursor podrá saltar sobre el "espacio" hacia la posición siguiente.

Cursor desplazable en conflictos de grabación procedentes de otro descriptor de sentencia

Piense en un ejemplo parecido al del apartado anterior, pero en el que el cursor de lectura es un cursor desplazable. Si es un cursor desplazable "insensible", esto no será un problema debido a que por definición el conjunto de resultados no cambia. Si el cursor no es "insensible", su comportamiento coincidirá con el cursor de lectura regular descrito anteriormente. En esencia, el comportamiento del cursor de lectura después del conflicto es que el conjunto de resultados vuelva a calcularse con arreglo a los datos de tabla más actuales y que se mantenga el comienzo del conjunto de filas actual. El cursor se avanza hacia la fila siguiente en el caso de que se suprima la fila actual.

El ejemplo siguiente ilustra el caso con un cursor desplazable utilizando CLP. Suponga que la tabla T tiene seis filas:

create table T (a int, b int)
     create index idx1 on T(a)
     insert into T values (1, 1)
     insert into T values (2, 2)
     insert into T values (3, 1)
     insert into T values (3, 2)
     insert into T values (3, 3)
     insert into T values (4, 4) 

Abusando de su generosidad, piense en un ejemplo en el que la aplicación tuviera dos descriptores de sentencia, uno para la lectura y el otro para la supresión.

Statement handle 1: enable scrollable cursor;
Statement handle 1: execute "SELECT A FROM T WHERE a < 10"
Statement handle 2: prepare "DELETE FROM T WHERE a = ?"
Statement handle 1: fetchscroll with SQL_FETCH_FIRST
-- get (1, 1)
Statement handle 1: fetchscroll with SQL_FETCH_NEXT
-- get (2, 2)
Statement handle 1: fetchscroll with SQL_FETCH_NEXT
-- get (3, 1)
Statement handle 2: execute
--- suppose delete row (2, 2)
Statement handle 1: fetchscroll with SQL_FETCH_NEXT
-- re-compute previous rows, and return (3, 2)
Statement handle 1: fetchscroll with SQL_FETCH_PRIOR
-- get (3, 1)
Statement handle 1: fetchscroll with SQL_FETCH_PRIOR
-- get (1, 1)  note that (2, 2) is gone
Statement handle 1: fetchscroll with SQL_FETCH_ABSOLUTE, offset 2
-- get (3, 1)  note that (2, 2) is gone
Statement handle 1: fetchscroll with SQL_FETCH_ABSOLUTE, offset 5
-- get (4, 4)

Cursor en confirmación y retrotracción, incluyendo la modalidad de confirmación automática

Sin tener en cuenta la modalidad de transacción o confirmación automática, un cursor abierto permanece abierto en la confirmación y un cursor abierto se cierra en la retrotracción.

Dependencia del objeto

Preparar una sentencia SQL por medio de un descriptor de sentencia H puede que produzca cierta dependencia de determinados objetos. Por ejemplo, seleccionar filas de una tabla T por medio de un Idx de índice requiere la existencia de la tabla T y del Idx de índice. Si otro descriptor de sentencia ha suprimido estos objetos (por ejemplo, si se ha descartado el Idx de índice), volver a ejecutar la sentencia por medio de H forzará una recompilación de la sentencia SQL. Como consecuencia, puede que el plan de consulta sea diferente o que se devuelva un error.