Savepoints in Firebird

Themen rund um den praktischen Einsatz von Firebird. Fragen zu SQL, Performance, Datenbankstrukturen, etc.

Moderator: thorben.braun

Antworten
zappa2
Beiträge: 31
Registriert: Fr 5. Okt 2018, 10:59

Hat hier jemand praktische Erfahrung im Umgang mit Savepoints?

In PSQL sind diese ja nicht erlaubt, nur wie handle ich sie denn dann?

Schreibe ich im IBExpert oder isql o.ä. komplett runter z.B.

insert..., Savepoint a, update..., savepoint b, delete ..., savepoint c und dann irgendwann Rollback to savepoint xyz oder Release Savepoint xyz

dann geht das. Nur setze ich diese Savepoints innerhalb einer Stored Proc und beende diese (natürlich ohne Commit oder Rollback) sind die trotzdem nicht greifbar. Was machen die denn dann praktisch für einen Sinn?

Ich hätte mir das ja bspw. so vorgestellt, dass man eine gewisse Abarbeitung eines Users schrittweise rückgängig machen könnte, also Savepoint für Savepoint von hinten her 'release'ed oder 'rollback'ed. So bleibt mir doch nach wie vor nur ein komplettes Commit oder Rollback.
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Hi zappa2,

Savepoints sind ein Snapshot innerhalb einer Transaktion. In PSQL sind diese aufgrund der notwendigen Atomität des Aufrufers nicht zugelassen. Dies sind allerdings Interna, die ich ebenfalls nicht ganz verstehe.
Ich hätte mir das ja bspw. so vorgestellt, dass man eine gewisse Abarbeitung eines Users schrittweise rückgängig machen könnte, also Savepoint für Savepoint von hinten her 'release'ed oder 'rollback'ed. So bleibt mir doch nach wie vor nur ein komplettes Commit oder Rollback.
Ist am Anfang etwas "komisch", aber die Savepoints sind nur innerhalb einer Transaktion gültig. Ist die Transaktion beendet, werden die Savepoints entfernt. Sicherungspunkte können also nur innerhalb einer Transaktion verwendet werden und ergeben nur bei "Stapelanweisungen", wie du bereits geschrieben hast, Sinn.

Gruß
Martin
Martin Köditz
it & synergy GmbH
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

In PSQL heißt das ganze "begin in autonomous transaction do....."
https://firebirdsql.org/refdocs/langref ... trans.html

Somit ist es in Prozeduren/Functions/Triggern möglich Aktionen in der Datenbank festzuschreiben, die von übergeordneten Transaktionen nicht rückgängig gemacht werden können.

Ich möchte z.B. in Triggern jeden Versuch einer Aktion auf einer Tabelle protokollieren.
Also kopiere ich bestimmte Informationen im Trigger in eine andere Tabelle und committe sie. Dabei erfolgt das Ganze eher automatisch, denn einen Commit/Rollback brauche ich nicht.

Da ich zur Laufzeit z.B. auch dynamisch Tabellen erstelle, blockiere ich die RDB$-Tabellen bis zum Commit.
Mache ich den Create aber in einer autonomen Transaktion, sind die Tabellen sofort wieder frei. Somit erstelle ich z.B. in einer Transaktion einen Index und setze ihn sofort inaktiv. Beim Commit passiert also nichts und die RDB$-Tabellen sind wieder frei.
Im nächsten Schritt setze ich den Index aktiv und committe diesen. DA ich in diesem Fall nur eine Zeile verändere kann nun in Ruhe der Index erstellt werden, während andere Transaktionen parallel ausgeführt werden können.
Denn ein normaler Create Index mit Commit baut im Commit sofort den Index auf und sperrt somit leider die gesamte RDB$-Tabelle gegen weitere Veränderungen.

Es gibt also viele Szenarien, autonome Transaktionen in PSQL durchzuführen.
Ich benutze dies auch in "execute block", da ich starre Prozeduren nicht flexibel genug finde.

Savepoints lassen sich innerhalb einer Transaktion dazu verwenden, die Verarbeitung in mehrere Schritte und Alternativen zu zerlegen.
Hat Variante A nicht geklappt, versuche Variante B.
Allerings sind sämtliche Aktionen nur temporär bis zum Commit der Transaktion. Beim Rollback wird trotzdem alles zurück gedreht.
Autonome Transaktionen innerhalb einer Transaktion sind save.
zappa2
Beiträge: 31
Registriert: Fr 5. Okt 2018, 10:59

Mal wieder Euch beiden fleißigen Schreibern besten Dank!

Unterm Strich sehe ich jetzt für mich als 'normalen' User von Firebird keinen Sinn in der eigenen Anwendung von Savepoints. Im Hinterkopf behalte ich mal noch die Möglichkeit, diese innerhalb eines EXECUTE BLOCK zu verwenden. Aber auch da habe ich ja keine Eingriffsmöglichkeit von außen, wegen der geforderten Atomizität der Transaktion.

Ich meine aber, mal in den IBDac-Komponenten o.ä. eine SavePoint-Komponente gesehen und verwendet zu haben, in dem von mir eingangs beschriebenem Szenarium (Insert - Savepoint - Update - Savepoint usw.). Und da konnte man richtig sagen, dass man z.B. die letzten 3 DB-Aktionen seit Beginn des letzten Commit/Rollback rückgängig machen konnte. Aber die werden wohl wie eine Art SQL-Log aufbauen, in dem ich einzelne Wiederherstellungspunkte anlaufen/setzen/rücksetzen kann, und das erst mit dem endgültigen Commit/Rollback ausführen. Nur kann man ja innerhalb dieses Blockes auf noch nicht committete Updates und Inserts zugreifen. Kann also kein EXECUTE BLOCK sein. Grübel, grübel...
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Mir fällt dazu auch nichts konkretes ein.
Auf Grund der Satzversionen und den daraus resultierenden möglichen Komplikationen sollten Transaktionen immer möglichst kurz gehalten sein.
Damit ist nicht die Menge der Informationen sondern die Dauer der Bearbeitungszeit gemeint.
Eine Rahmenbedingung war auch immer:
Eine Transaktion soll auch nie über eine länger dauernde Interaktion, also i.W. Benutzereingriffe in Form von Eingaben sein. Wenn der gerade vom Hocker fällt kann das ganze System im Endeffekt nicht weiterarbeiten.
Der SQL-Server macht sich das i.d.R. einfach, in dem er beim Update/Insert/Delete die gesamte Tabelle bis zum Commit sperrt. Deshalb empfehlen die SQL-Server-Spezies auch immer gerne Transaktionen in Procedures durchzuführen, denn dadurch sind Usereingriffe eben nicht möglich. Durch die Sperre ist i.Ü.auch kein Select möglich. Alle Transaktionen werden bis zum Commit geparkt.
Wie sich der SQL-Server da nur durchsetzen konnte verstehe ich bis heute noch nicht.
Ich denke, das liegt nur an der extrem guten Programmierunterstützung der IDE's.

Wenn bei einer Transaktion sowieso ein Rollback gemacht werden müsste, sind die Savepoints ja egal. Also ist es ggf. eine konzeptionelle Schwäche, wenn man auf Savepoints angewiesen ist.

Wenn man aber sein Konzept auf die sog. Belegebene stellt (Kopfsatz, Positionen, abhängige Daten) ergibt sich automatisch das Transaktionskonzept.
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Wie sich der SQL-Server da nur durchsetzen konnte verstehe ich bis heute noch nicht.
Ich denke, das liegt nur an der extrem guten Programmierunterstützung der IDE's.
Nicht zu vergessen das milliardenschwere Marketing. :D

Gruß
Martin
Martin Köditz
it & synergy GmbH
Antworten