Anuncios en tutorial de programación PLSQL

viernes, 11 de octubre de 2013

Uso de Rollback Segments por sentencias SELECT

Uso de Rollback Segments en sentencias SELECT
En alguna ocasión algún lector me ha preguntado, con cierta sorpresa, acerca del por qué una sentencia SELECT le fallaba con el mensaje de error "No es posible ampliar el segmento de rollback" ("Unable to extend rollback segment"). La sorpresa proviene del hecho de que son muchos los desarrolladores PL/SQL los que piensan que los segmentos de rollback sólo se utilizan cuando se emplean sentencias PLSQL en las que se modifican o actualizan datos dentro de la base de datos Oracle. Bajo este tipo de pensamiento es normal que, cuando se produce el error mencionado anteriormente al ejecutar una sentencia SELECT, uno se pregunte: ¿utiliza la base de datos Oracle segmentos de rollback al ejecutar sentencias SELECT?

Bueno, en mi opinión, lo primero que hay que hacer es reformular la pregunta y cambiarla por la siguiente: ¿una sentencia SELECT necesita crear o leer segmentos de rollback? La pregunta formulada de esta manera seguro que nos ayudará a comprender mejor este artículo, ya que el verbo "utilizar" usado en la primera pregunta no es lo suficientemente específico.

En PL/SQL, todas las sentencias SELECT tienen el potencial de utilizar los datos de rollback o undo (o datos de vuelta atrás). La base de datos Oracle a la hora de procesar cualquier tipo de consulta utiliza los segmentos de rollback para producir conjuntos de resultados de lectura consistente (la lectura consistente es una característica de las bases de datos Oracle que asegura que todos los registros dentro de un conjunto de resultados, cuando son presentados a una aplicación PLSQL o a cualquier otro tipo de aplicación, provengan de un mismo instante de tiempo).

No obstante, este uso de los segmentos de rollback no va a causar nunca por sí solo un error como el antes mencionado (ORA-01650 Unable to extend rollback segment... u ORA-01651 Unable to extend undo segment... ). Sin embargo, sí que puede provocar un error del tipo "ORA-01555 Snapshot too old".

Para que una sentencia SELECT pueda generar los errores ORA-01650 u ORA-01651, es necesario que esté generando segmentos de rollback y los motivos pueden ser los siguientes:
  • La sentencia SELECT contiene la cláusula FOR UPDATE.
  • La funcionalidad de auditoría está habilitada.
  • La sentencia SELECT invoca a algún tipo de transacción que escribe en la base de datos Oracle.

Lo más corriente es que la causa sea que la sentencia SELECT contenga una cláusula FOR UPDATE, cuando esto ocurre la base de datos Oracle bloquea todos los registros necesarios antes de que la sentencia SELECT empiece a devolver resultados, y bloquear un registro en la base de datos Oracle implica modificar un bloque de la base de datos para registrar dicho bloqueo. Por otro lado, cada vez que se modifica un bloque de la base de datos, se necesita generar un undo para esa operación.

Demostrar este hecho es muy sencillo. Creemos una sesión SQL y ejecutemos los siguientes comandos sin que haya ningún otro usuario utilizando la base de datos:

SQL> SELECT used_ublk FROM v$transaction

No rows selected

SQL> BEGIN
  2    FOR cursor IN (
  3      SELECT * FROM nombre_tabla
  4        FOR UPDATE)
  5    LOOP null;
  6    END LOOP;
  7  END;
  10 /

PL/SQL procedure successfully completed.

SQL> SELECT used_ublk FROM v$transaction

USED_UBLK
---------
      932

SQL> COMMIT;

Según queríamos confirmar, podemos ver que la ejecución de la sentencia SELECT FOR UPDATE ha generado 932 bloques de undo (tened en cuenta que nombre_tabla debe ser una tabla que exista en vuestra base de datos Oracle).

0 comentarios: