Viniendo desde el mundo MS SQL, tiendo a hacer un uso intensivo de los procedimientos almacenados. Actualmente estoy escribiendo una aplicación que usa muchas funciones de PostgreSQL plpgsql. Lo que me gustaría hacer es deshacer todos los INSERTOS/ACTUALIZACIONES contenidos dentro de una función en particular si recibo una excepción en algún punto dentro de ella.PostgreSQL: ¿Retirar una transacción dentro de una función plpgsql?
Originalmente tenía la impresión de que cada función está envuelta en su propia transacción y que una excepción automáticamente revertiría todo. Sin embargo, ese no parece ser el caso. Me pregunto si debería usar puntos de rescate en combinación con el manejo de excepciones. Pero realmente no entiendo la diferencia entre una transacción y un punto de rescate para saber si este es el mejor enfoque. ¿Algún consejo, por favor?
CREATE OR REPLACE FUNCTION do_something(
_an_input_var int
) RETURNS bool AS $$
DECLARE
_a_variable int;
BEGIN
INSERT INTO tableA (col1, col2, col3)
VALUES (0, 1, 2);
INSERT INTO tableB (col1, col2, col3)
VALUES (0, 1, 'whoops! not an integer');
-- The exception will cause the function to bomb, but the values
-- inserted into "tableA" are not rolled back.
RETURN True;
END; $$ LANGUAGE plpgsql;
¿Se puede publicar un ejemplo de una función que no revierte todo como era de esperar? Las funciones PL/pgSQL * do * se ejecutan dentro del contexto de transacción de la declaración de llamada, pero un bloque BEGIN..EXCEPTION puede modificar ese comportamiento. Sin ver un ejemplo, es difícil dar el consejo adecuado. –
Editado para agregar un ejemplo. Gracias. – jamieb
Estoy ejecutando 8.4.2, creé tableA y B con tres columnas int cada una, ejecuto su ejemplo (con ";" eliminado al final de INSERT INTO tableB line) y se bombardeó. Revisé ambas mesas y ambas estaban vacías. Incluso agregué un código de depuración entre los dos para verificar que el registro estaba allí antes de que fallara, y luego desapareció después de la falla. –