Aus der MS SQL-Welt kommend tendiere ich dazu, gespeicherte Prozeduren stark zu nutzen. Ich schreibe gerade eine Anwendung verwendet eine Menge von PostgreSQL plpgsql Funktionen. Ich möchte alle INSERTS/UPDATES, die in einer bestimmten Funktion enthalten sind, zurücksetzen, wenn ich an irgendeiner Stelle eine Ausnahme erhalte.PostgreSQL: Rollback einer Transaktion innerhalb einer Plpgsql-Funktion?
Ich hatte ursprünglich den Eindruck, dass jede Funktion in eine eigene Transaktion eingebunden ist und dass eine Ausnahme automatisch alles rückgängig machen würde. Dies scheint jedoch nicht der Fall zu sein. Ich frage mich, ob ich Savepoints in Kombination mit der Ausnahmebehandlung verwenden sollte? Aber ich verstehe den Unterschied zwischen einer Transaktion und einem Sicherungspunkt nicht wirklich, um zu wissen, ob dies der beste Ansatz ist. Irgendwelche Beratung bitte?
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;
Können Sie ein Beispiel für eine Funktion posten, die nicht alles zurücksetzt, wie Sie es erwarten würden? PL/pgSQL-Funktionen * do * werden innerhalb des Transaktionskontextes der aufrufenden Anweisung ausgeführt, aber ein BEGIN..EXCEPTION-Block kann dieses Verhalten ändern. Ohne ein Beispiel zu sehen, ist es schwierig, den richtigen Rat zu geben. –
Bearbeitet, um ein Beispiel hinzuzufügen. Vielen Dank. – jamieb
Ich lief 8.4.2, erstellt TabelleA und B mit drei int Spalten jeweils, führen Sie Ihr Beispiel (mit ";" am Ende der INSERT INTO tableB Zeile entfernt) und es bombardiert. Ich überprüfte beide Tische und sie waren beide leer. Ich habe sogar einen Debug-Code zwischen den beiden hinzugefügt, um zu verifizieren, dass der Datensatz dort war, bevor er fehlschlug, dann war er nach dem Fehler verschwunden. –