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?

Alex
quelle

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.

Hans-Jürgen Schönig
quelle
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.

dezso
quelle
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.

Amir Ali Akbari
quelle
0

Ab Postgresql 9.5 können Sie dynamische Hintergrund-Worker verwenden, die von der Erweiterung pg_background bereitgestellt werden. Es entsteht eine autonome Transaktion. Bitte beziehen Sie sich auf die Github-Seite der Erweiterung. Die Lösung ist besser als db_link. Es gibt eine vollständige Anleitung zur Unterstützung autonomer Transaktionen in PostgreSQL

shcherbak
quelle