Saltar al contenido
Codifíca.me | Desarrollo web | Programación

Transacciones autónomas en ORACLE

21 septiembre, 2010

A veces, es necesario que una parte de las transacciones se graben, independientemente de si el resto ha dado error. Por ejemplo, si queremos guardar un registro de los errores producidos en un procedimiento que inserta varios registros en una tabla y tiene controlados los fallos con un rollback.

Esto se consigue marcando el bloque PLSQL con PRAGMA AUTONOMOUS_TRANSACTION. Con esta directiva conseguimos que las transacciones se comporten de manera diferente al principal. Mejor lo vemos con un ejemplo.

Creamos dos tablas:

create table PRUEBA (nombre varchar2(1));
create table PRUEBA_LOG (descripcion varchar2(200), fecha date);

Ahora un procedimiento que grabará en un tabla de errores los registros que no insertemos y un bloque que insertará registros del 1 al 10 enPRUEBA. El último registro (10) fallará porque la longitud del campo es de 1.

 CREATE OR REPLACE PROCEDURE ERR_LOG(VALOR VARCHAR2)
 IS
 PRAGMA AUTONOMOUS_TRANSACTION;
 BEGIN
 INSERT INTO PRUEBA_LOG
 (DESCRIPCION, FECHA)
 VALUES
 (VALOR, SYSDATE);
 COMMIT;
 END;
/
BEGIN
  INSERT INTO PRUEBA
  SELECT level  FROM dual
  CONNECT BY level <= 10;
  COMMIT;
EXCEPTION
  WHEN OTHERS THEN
    ERR_LOG(SQLERRM);
    ROLLBACK;
END;

Al terminar de ejecutar el proceso, hacemos una select de la tabla de errores y nos devuelve esto:

SQL> select * from PRUEBA_LOG;

ORA-12899: value too large for column “MANTE90″.”PRUEBA”.”NOMBRE” (actual: 2, ma
ximum: 1)
06-AGO-2010

Como veis el commit del procedimiento actua de manera independiente al bloque. Y ha podido realizar el commit cuando el registro ha fallado ya que esta marcado como una transacción autónoma.

Es un pequeño ejemplo para guardar un log sobre registros que falla, pero si ya estais trabajando con Oracle10g, es mucho mejor trabajar con el paquete DML ERROR LOGGING. Echadle un ojo si os interesa (está posteado en esta página).