2008-10-15 23 views
11

Estoy trabajando en scripts que aplican actualizaciones de esquema de base de datos. Configuré todos mis scripts de actualización de SQL usando start transaction/commit. Paso estos scripts a psql en la línea de comando.Transacciones anidadas en postgresql 8.2?

Ahora necesito aplicar varias secuencias de comandos al mismo tiempo, y en una transacción. Hasta ahora, la única solución que he encontrado es eliminar la transacción de inicio/confirmación del conjunto original de scripts, luego unirlos dentro de un nuevo bloque de inicio/transacción de inicio. Estoy escribiendo guiones Perl para hacer esto sobre la marcha.

Efectivamente quiero transacciones anidadas, que no puedo entender cómo hacer en postgresql.

¿Hay alguna manera de hacer o simular transacciones anidadas para este fin? Tengo las cosas configuradas para rescatar automáticamente cualquier error, por lo que no es necesario que continúe en la transacción de nivel superior si falla alguno de los más bajos.

Respuesta

5

Bueno, tiene la posibilidad de usar transacciones anidadas dentro de postgresql usando SavePoints.

Tome este ejemplo de código:

CREATE TABLE t1 (a integer PRIMARY KEY); 

CREATE FUNCTION test_exception() RETURNS boolean LANGUAGE plpgsql AS 
$$BEGIN 
    INSERT INTO t1 (a) VALUES (1); 
    INSERT INTO t1 (a) VALUES (2); 
    INSERT INTO t1 (a) VALUES (1); 
    INSERT INTO t1 (a) VALUES (3); 
    RETURN TRUE; 
EXCEPTION 
    WHEN integrity_constraint_violation THEN 
     RAISE NOTICE 'Rollback to savepoint'; 
     RETURN FALSE; 
END;$$; 

BEGIN; 

SELECT test_exception(); 
NOTICE: Rollback to savepoint 
test_exception 
---------------- 
f 
(1 row) 

COMMIT; 

SELECT count(*) FROM t1; 
count 
------- 
    0 
(1 row) 

Tal vez esto le ayudará a salir un poco.

+0

Para usar puntos de rescate en este caso, tendría que modificar mis scripts existentes y cómo se ejecutan. En este caso particular, si fuera a hacer eso, simplemente eliminaría el bloque de transacción de inicio/final de todos mis scripts y lo agregaría por separado, lo que facilitaría hacer varios a la vez. Gracias! –

0

Terminé 'solucionando' mi problema fuera de banda. Utilizo un script de perl para volver a trabajar los scripts de entrada para eliminar sus llamadas de inicio de transacción/confirmación, y luego insertarlos en un solo archivo, lo que hace que sea inicio/transacción de inicio propio.

Cuestiones relacionadas