Frage zu Triggern und Rollback bzw. Commit

Hallo!
Ich beschäftige mich gerade das erste mal mit der Programmierung von Triggern. Zu folgender Frage habe ich bisher noch keine Antwort gefunden:
Wie Verhalten sich Trigger im Zusammenhang mit Transaktionen?
Angenommen ein Insert auf Tabelle A löst einen Trigger aus, der in Tabelle B etwas verändert. Nun kommt es aber zu einem Rollback, d.h. das Insert auf Tabelle A wird NICHT ausgeführt.
Was passiert?
Meine Vermutung bzw. Hoffnung wäre, dass der Trigger erst nach einem Commit ausgelöst wird.
Wer kann man dazu etwas sagen?
Ganz allgemein wäre ich auch an Webadressen zum Thema Trigger und PostgreSQL interessiert.
Gruß, Christian

Deine Vermutung ist falsch. Die gesamte Operation wird innerhalb einer Transaktion ausgeführt, die Trigger werden also auch innerhalb der Transaktion ausgelöst.

Näheres zu Triggern im Allgemeinen sagt die Doku:
http://www.postgresql.org/docs/current/interactive/sql-createtrigger.html
Zu PostgreSQL gibt es sehr umfangreiche Dokumentationen und Bücher unter: http://www.postgresql.org/

Warum möchtest du den Trigger erst nach dem Commit auslösen?

Hallo adds!

Danke für die Info, auch wenn ich es mir anders gewünscht hätte.
Hintergrund: Ich wollte eine (asynchrone) Datenreplikation auf Basis von Triggern realisieren, ähnlich wie dies z.B. beim Daffodil Replicator der Fall ist. Bei jedem Update, Delete oder Insert soll die enstprechen Operation per Trigger protokolliert werden. Beim späteren Synchronisationsvorgang würden dann die protokollierten Operationen auf den jeweils anderen Rechner übernommen werden. Hierbei sollen aber natürlich nur tatsächlich durchgeführte Operationen berücksichtigt werden. Protokolliert der Trigger aber auch Operation, die durch ein Rollback zurückgedreht wurden, erhalte ich bei der Datenreplikation auf der Gegenseite inkonsistente Daten.

Ich frage mich, wie triggerbasierte Replikationslösungen funktionieren sollen, wenn der Trigger bereits vor dem commit ausgelöst wird…

Gruß, Christian

Also, äh, hast du dir schon mal Slony angeschaut?
Genau dafür wurden aber auch zweiphasige Commits geschaffen, um das realisieren zu können.

Man muss das Rad ja nicht neu erfinden :wink:

Nach meinem Wissen funktioniert Slony nur dann, wenn alle Rechner permanent miteinander verbunden sind. Ich suche jedoch nach einer Lösung, wo die Rechner temporär das Netz verlassen und nicht mehr erreichbar sind. Oder ist mein Wissenstand hier falsch bzw. nicht mehr aktuell?

Das Thema “zweiphasige Commit” muß ich mir mal ansehen…

Gruß, Christian

Hmm, das wird komplizierter, du müsstest praktisch loggen, was passiert und das Log bei Bedarf abspulen.

Eine Möglichkeit dafür wäre PITR (Point in Time Recovery), eine andere hatte ich mal entwickelt: tablelog.
Das loggt alle Änderungen an einer Tabelle mit, war aber nicht primär dafür gedacht, die Änderungen nun an eine zweite Tabelle zu spoolen. Das liesse sich aber wohl daraus umsetzen.

Nun, Prinzip tablelog wäre: der Trigger wird in der Transaktion ausgelöst. Kommt es dabei zu Problemen, werden auch die Änderungen an der Loggingtabelle zurückgerollt, als wäre nichts geschehen. Erst nach dem Commit stehen die geloggten Daten bereit und könnten übertragen werden.

Wenn du gedenkst, auf so einen Ansatz aufzusetzen, kontaktiere mich mal bitte privat, mal sehen, ob sich da neue Ideen für tablelog ergeben.

Die Logfiles des PITR zu nutzen könnte ein brauchbarer Ansatz sein. Dein tablelog hört sich aber fast noch interessanter an.
Würde gern mehr darüber erfahren…! :slight_smile:

Nochmal zurück zu meiner Ausgangsfrage:
Trigger werden bereits vor dem Commit ausgelöst. Ok.
Was passiert bei einem Rollback? Hier müßten dann doch auch die per Trigger ausgelösten Operationen zurückgedreht werden.
Ansonsten würde man beim Einsatz von Triggern die referentielle Integrität der Daten gefährden, was ein Armutszeugnis für PostreSQL wäre (und was ich deshalb auch kaum glauben kann… :slight_smile:

Hallo Christian,

ich will mal hoffen, dass Du dir das Armutszeugnis nicht selbst ausstellen muss. Was Du bisher nicht verstanden hast, sind Transaktionen und wie sie funktionieren.

In der Doku kanst Du folgendes lesen

Transaktionen sind ein grundlegendes Konzept aller Datenbanksysteme. Die wichtigste Eigenschaft einer Transaktion ist, dass sie mehrere Schritte zu einer einzigen > Alles-oder-nichts-Operation > zusammenfasst. Die Stadien zwischen den Schritten sind für andere, gleichzeitig ausgeführte Transaktionen nicht sichtbar, und falls irgendein Fehler passiert, der verhindert, dass die Transaktion beendet wird, dann haben die Schritte der Transaktion überhaupt keine Auswirkung auf die Datenbank.

Eine Transaktion umfast die Ausführung aller Befehle, die zwischen dem Befehl BEGIN und COMMIT liegen. Wird während der Transaktion ein Fehler festgestellt, wird ein ROLLBACK ausgeführt. Ein ROLLBACK rollt die aktuelle Transaktion zurück und sorgt dafür, dass alle von der Transaktion getätigten Änderungen verworfen werden.

Zum technischen Verständnis, ganz allgemein: Während einer Transaktion wird kein Original-Datensatz geändert. Die Änderungen eines Datensatzes werden in einer Kopie des Original-Datensatzes geschrieben. Wird der Befehl COMMIT erreicht, werden die Original-Datensätze durch die geänderten Datensätze (Kopie) ersetzt. Das geht sehr schnell, z.B. indem man den Zeiger auf den Datensatz ändert. Die Ausführungszeit ist gegeüber der Ausführungszeit der Transaktion im allgemeinen sehr klein. Damit keine Probleme enstehen sind alle Zugriffe während des COMMITs auf die entsprechenden Tabellen gesperrt. Erst wenn die Sperrung der Tabellen wieder aufgehoben ist, sind die geänderten Datensätze für alle sichtbar. Der Befehl ROLLBACK macht nichts anderes, was man in der Programmierung unter “aufräumen” versteht.

Die Feinheiten von Transaktionen solltest Du in der Doku nachlesen.



mfg

fristo

Hallo fristo!

Meine Unsicherheit beruhte eigentlich einzig und allein darin, ob es für die Datenbank einen Unterschied macht, ob eine Operation von mir als Anwender / meinem Programm oder durch Trigger ausgelöst wurde. Es macht keine Unterschied, habe ich nun verstanden. Mein Weltbild ist damit in Ordnung und niemandem muß ein Armutszeugnis ausgestellt werden. :wink:

Irgendwie hatte ich im Hinterkopf das es mit Triggern da zu Problemen kommen kann. Mag sein, dass das mal vor 10 oder noch mehr Jahren so war (bei anderen DBMS), mag aber auch sein, dass ich mich total irre und was verwechsle.

Auf jeden Fall danke für die ausführlichen Informationen, dir mir sehr geholfen haben.

Gruß, Christian