Transacciones autónomas
Las transacciones autónomas le permiten salir del contexto de la transacción de llamada, realizar una transacción independiente y regresar a la transacción de llamada sin afectar su estado. La transacción autónoma no tiene ningún vínculo con la transacción que realiza la llamada, por lo que ambas transacciones solo pueden compartir los datos comprometidos.
Los siguientes tipos de bloques PL / SQL se pueden definir como transacciones autónomas:
Procedimientos y funciones almacenados.
Procedimientos y funciones locales definidos en un bloque de declaración PL / SQL.
Procedimientos y funciones empaquetados.
Métodos de tipo.
Bloques anónimos de nivel superior.
La forma más fácil de comprender las transacciones autónomas es verlas en acción. Para hacer esto, creamos una tabla de prueba y la llenamos con dos filas. Tenga en cuenta que los datos no están comprometidos.
CREATE TABLE at_test (
id NUMBER NOT NULL,
description VARCHAR2(50) NOT NULL
);
INSERT INTO at_test (id, description) VALUES (1, ‘Description for 1’);
INSERT INTO at_test (id, description) VALUES (2, ‘Description for 2’);
SELECT * FROM at_test;
ID DESCRIPTION
———- ————————————————–
1 Description for 1
2 Description for 2
2 rows selected.
SQL>
A continuación, insertamos otras 8 filas usando un bloque anónimo declarado como una transacción autónoma, que contiene una declaración de confirmación.
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
FOR i IN 3 .. 10 LOOP
INSERT INTO at_test (id, description)
VALUES (i, ‘Description for ‘ || i);
END LOOP;
COMMIT;
END;
/
PL/SQL procedure successfully completed.
SELECT * FROM at_test;
ID DESCRIPTION
———- ————————————————–
1 Description for 1
2 Description for 2
3 Description for 3
4 Description for 4
5 Description for 5
6 Description for 6
7 Description for 7
8 Description for 8
9 Description for 9
10 Description for 10
10 rows selected.
SQL>
Como era de esperar, ahora tenemos 10 filas en la tabla. Si ahora emitimos una declaración de reversión, obtenemos el siguiente resultado.
ROLLBACK;
SELECT * FROM at_test;
ID DESCRIPTION
———- ————————————————–
3 Description for 3
4 Description for 4
5 Description for 5
6 Description for 6
7 Description for 7
8 Description for 8
9 Description for 9
10 Description for 10
8 rows selected.
SQL>
Las 2 filas insertadas por nuestra sesión actual (transacción) se han revertido, mientras que las filas insertadas por las transacciones autónomas permanecen. La presencia de la directiva del compilador PRAGMA AUTONOMOUS_TRANSACTION hizo que el bloque anónimo se ejecutara en su propia transacción, por lo que la declaración de confirmación interna no afectó a la sesión de llamada. Como resultado, la reversión aún podía afectar el DML emitido por la declaración actual.
Las transacciones autónomas se utilizan comúnmente en las rutinas de registro de errores, donde los mensajes de error deben conservarse, independientemente del estado de confirmación / reversión de la transacción. Por ejemplo, la siguiente tabla contiene mensajes de error básicos.
CREATE TABLE error_logs (
id NUMBER(10) NOT NULL,
log_timestamp TIMESTAMP NOT NULL,
error_message VARCHAR2(4000),
CONSTRAINT error_logs_pk PRIMARY KEY (id)
);
CREATE SEQUENCE error_logs_seq;
Definimos un procedimiento para registrar mensajes de error como una transacción autónoma.
CREATE OR REPLACE PROCEDURE log_errors (p_error_message IN VARCHAR2) AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO error_logs (id, log_timestamp, error_message)
VALUES (error_logs_seq.NEXTVAL, SYSTIMESTAMP, p_error_message);
COMMIT;
END;
/
El siguiente código fuerza un error, que se captura y se registra.
BEGIN
INSERT INTO at_test (id, description)
VALUES (998, ‘Description for 998’);
— Forzar inserción no válida.
INSERT INTO at_test (id, description)
VALUES (999, NULL);
EXCEPTION
WHEN OTHERS THEN
log_errors (p_error_message => SQLERRM);
ROLLBACK;
END;
/
PL/SQL procedure successfully completed.
SELECT * FROM at_test WHERE id >= 998;
no rows selected
SELECT * FROM error_logs;
ID LOG_TIMESTAMP
———- —————————————————————————
ERROR_MESSAGE
—————————————————————————————————-
1 28-FEB-2006 11:10:10.107625
ORA-01400: cannot insert NULL into (“TIM_HALL”.”AT_TEST”.”DESCRIPTION”)
1 row selected.
SQL>