Transaktionen innerhalb einer Transaktion


17

Welches Verhalten würde PostgreSQL anzeigen, wenn beispielsweise das folgende Skript aufgerufen würde?

BEGIN;
SELECT * FROM foo;
INSERT INTO foo(name) VALUES ('bar');
BEGIN; <- The point of interest
END;

Würde PostgreSQL die zweite verwerfen BEGINoder würde implizit ein Commit festgelegt und der BEGIN ENDBlock am Ende als separate Transaktion ausgeführt?

Antworten:


12

Was Sie benötigen, ist eine sogenannte "autonome Transaktion" (eine Funktion, die von Oracle bereitgestellt wird). Zu diesem Zeitpunkt ist dies in PostgreSQL noch nicht möglich. Sie können jedoch SAVEPOINT s verwenden:

BEGIN;
INSERT ...
SAVEPOINT a;
some error;
ROLLBACK TO SAVEPOINT a;
COMMIT;

Es ist keine vollständig autonome Transaktion - aber es ermöglicht Ihnen, "jede Transaktion" richtig zu machen. Sie können es verwenden, um das zu erreichen, was Sie von autonomen Transaktionen erwarten.

Ansonsten gibt es derzeit keine andere vernünftige Lösung.


13

Sie könnten es selbst versuchen:

WARNUNG: Es wird bereits eine Transaktion ausgeführt

Es wird keine neue (Unter-) Transaktion gestartet, da verschachtelte Transaktionen in PostgreSQL nicht implementiert sind. (Sie können in einer pl/pgsqlFunktion zaubern , die beispielsweise dieses Verhalten nachahmt.)

Mit PostgreSQL 11 könnte man meinen, dass die neuen realen gespeicherten Prozeduren und ihre Fähigkeit, Transaktionen zu verarbeiten, geschachtelte Transaktionen ermöglichen würden. Laut Dokumentation ist dies jedoch nicht der Fall:

In vom CALLBefehl aufgerufenen Prozeduren sowie in anonymen Codeblöcken ( DOBefehl) ist es möglich, Transaktionen mit den Befehlen COMMITund zu beenden ROLLBACK. Eine neue Transaktion wird automatisch gestartet, nachdem eine Transaktion mit diesen Befehlen beendet wurde. Daher gibt es keinen separaten START TRANSACTION-Befehl.


9

PostgreSQL unterstützt keine Subtransaktionen, aber die SAVEPOINTFunktion kann Ihre Anforderungen effektiv erfüllen. Zitat aus der Dokumentation für Advanced Access Layer zu PG über Versprechen von Vitaly Tomilov auf GitHub:

PostgreSQL unterstützt keine ordnungsgemäße Unterstützung für verschachtelte Transaktionen, sondern nur teilweise Rollbacks über Sicherungspunkte in Transaktionen. Der Unterschied zwischen den beiden Techniken ist enorm, wie weiter unten erläutert wird.

Eine ordnungsgemäße Unterstützung für verschachtelte Transaktionen bedeutet, dass das Ergebnis einer erfolgreichen Subtransaktion nicht zurückgesetzt wird, wenn die übergeordnete Transaktion zurückgesetzt wird. Bei PostgreSQL-Sicherungspunkten wird beim Zurücksetzen der Transaktion der obersten Ebene auch das Ergebnis aller inneren Sicherungspunkte zurückgesetzt.

Sicherungspunkte können für Teil-Rollbacks zu einem früheren Zeitpunkt innerhalb einer aktiven Transaktion verwendet werden. Um beispielsweise einen Sicherungspunkt einzurichten und später die Auswirkungen aller Befehle rückgängig zu machen, die nach dem Einrichten ausgeführt wurden:

BEGIN;
    INSERT INTO table1 VALUES (1);
    SAVEPOINT my_savepoint;
    INSERT INTO table1 VALUES (2);
    ROLLBACK TO SAVEPOINT my_savepoint;
    INSERT INTO table1 VALUES (3);
COMMIT;

Die obige Transaktion fügt die Werte 1 und 3, aber nicht 2 ein. SAVEPOINTWeitere Informationen finden Sie in der Dokumentation.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.