Lexikon

Geschachtelte Transaktionen

Transaktionen sind ein fundamentales Konzept in Datenbanksystemen, das auch im Bereich der Betriebssysteme und Programmiersprachen zunehmende Beachtung findet . Ein Programm wird als Transaktionsprogramm und eine aus seiner Ausführung resultierende Folge von Aktionen als Transaktion bezeichnet, wenn das zugrundeliegende Laufzeitsystem dafür bestimmte Eigenschaften gewährleistet: Aus der Sicht des Anwenders und des Anwendungsprogrammierers sind Transaktionen atomarpersistent und untereinander isoliert, d.h. die Effekte einer Transaktion kommen selbst im Fall eines Systemzusammenbruchs stets entweder vollständig oder gar nicht zum Tragen (Atomarität), nach erfolgreicher Beendigung einer Transaktion wird die Dauerhaftigkeit aller Änderungen permanenter Daten garantiert (Persistenz), und schließlich werden unerwünschte Wechselwirkungen mit parallelen Transaktionen durch geeignete Systemmaßnahmen ausgeschlossen (Isolation. Darüber hinaus kann ein Programm bei negativem Resultat anwendungsspezifischer Konsistenzprüfungen auch von sich aus den Abbruch einer Transaktion erzwingen (Konsistenzerhaltung). Diese Eigenschaften des Transaktionskonzepts werde in der Literatur auch unter dem Begriff „ACID-Prinzip" (Atomicity, Consistency, Isolation, Durability) zusammengefaßt.

Eine typische Anwendung, bei der sich das Transaktionskonzept bewährt hat, sind beispielsweise Flugreservierungssysteme, wobei einzelne Transaktionen im allgemeinen relativ kurz sind. Im Zusammenhang mit komplexeren, sogenannten „Non-Standard"-Anwendungen sowie der Verwendung von Transaktionen als allgemeines Programmierinstrument wurde jedoch die berechtigte Kritik laut, daß das klassische Transaktionskonzept in verschiedener Hinsicht zu unflexibel ist . Geschachtelte Transaktionen bieten demgegenüber die Möglichkeit, daß Aktionen selbst wiederum Transaktionen sein können und somit - zumindest teilweise - die Eigenschaften Atomarität, Persistenz und Isolation haben. Das klassische Beispiel einer geschachtelten Transaktion ist die „Urlaubsbuchung". Abbildung 1 zeigt die Struktur dieses Transaktionstyps.

Geschlossen geschachtelte Transaktionen

Die konventionelle Realisierung einer „Urlaubsbuchung" als flache Transaktion hat zwei entscheidende Nachteile: zum einen führt jede Fehlersituation während ihres Ablaufs zwingend zum Zurücksetzen der gesamten Anwendungstransaktion; und zum anderen müssen die einzelnen Teilschritte in der Regel nacheinander ausgeführt werden, wenn die Möglichkeit nicht ausgeschlossen werden kann, daß verschiedene Aktionen zum Teil auf dieselben Daten zugreifen (unter Einschluß von systeminternen Daten wie z.B. Zugriffspfaden). Geschachtelte Transaktionen in der vor allem durch bekannt gewordenen Form, die auch "geschlossen geschachtelte Transaktionen" genannt werden, beseitigen diese beiden Schwachpunkte des klassischen Transaktionskonzepts. Sie erlauben flexiblere Rücksetzmöglichkeiten im Sinne des altbekannten "Savepoint"-Konzepts, und sie gestatten es, Subtransaktionen derselben Anwendungstransaktion parallel auszuführen.

Subtransaktionen haben in diesem Ansatz - unabhängig von ihrer Schachtelungstiefe - die Eigenschaft der Atomarität. Persistenz dagegen wird lediglich für die gesamte Anwendungstransaktion garantiert. Ein in einer Subtransaktion aufgetretener Fehler führt zunächst nur zum Zurücksetzen der direkt betroffenen Subtransaktionen. Dies wird der unmittelbaren Vatertransaktion mitgeteilt, die daraufhin entscheiden kann, die gescheiterte Subtransaktion neu zu starten oder ihre eigene Rücksetzung zu veranlassen. Je nach der gerade vorliegenden Schachtelungstiefe ergeben sich somit zu jedem Zeitpunkt i.a. mehrere potentielle Intratransaktions-Rücksetzpunkte. Die Möglichkeit, Fehler gewissermaßen lokal, d.h. innerhalb von Subtransaktionsgrenzen zu handhaben, macht sich insbesondere in einem verteilten System bezahlt. Im „Urlaubsbuchungs"-Szenario z.B. liegt die Annahme nahe, daß Flugbuchung, Hotelreservierung und Mietwagenreservierung in verschiedenen Rechnern ablaufen. Bei einem lokalen Fehler während der Ausführung der „Mietwagen"-Subtransaktion (z.B. Rechnerausfall, lokaler Deadlock o.ä.) genügt es, nur die betroffene Subtransaktion zurückzusetzen und erneut zu starten.

In einem verteilten System - sowie generell zur besseren Ressourcenauslastung - drängt es sich förmlich auf, die verschiedenen Aktionen einer „Urlaubsbuchung" zumindest teilweise parallel auszuführen. Eine wesentliche Voraussetzung für diese Art der Intratransaktions-Parallelität ist, daß es zwischen den parallelen Aktionen ein- und derselben Anwendungstransaktion keinerlei Konflikte bei den Zugriffen auf gemeinsam benutzte Daten und Speicherstrukturen gibt. Da diese Bedingung gerade auf die Eigenschaft der Isolation von Transaktionen hinausläuft, garantiert die Ausführung von Aktionen als Subtransaktionen in der Tat, daß diese voneinander isoliert sind, ohne dabei die Parallelität unnötig einzuschränken. Im Beispiel könnten die drei Schritte „Flug", „Hotel" und „Mietwagen" gleichzeitig angestoßen werden, und innerhalb der „Flug"-Subtransaktion könnten wiederum die Buchung des „Hinflugs" und des „Rückflugs" parallel erfolgen, sofern geeignete „Concurrency-Control"-Maßnahmen angewandt werden, wie z.B. die in vorgeschlagene Erweiterung des klassischen strikten Zweiphasen-Sperrprotokolls. Sperren werden dabei jeweils bis zum Ende einer Subtransaktion gehalten, so daß parallele Subtransaktionen desselben Vaters voneinander isoliert sind. Bei Beendigung einer Subtransaktion werden Sperren an die jeweilige Vatertransaktion „vererbt" und erst beim Ende der gesamten Anwendungstransaktion endgültig freigegeben. Wegen dieser von herkömmlichen Transaktionen gewohnten - strengen Isolation paralleler Anwendungstransaktionen untereinander wird diese Variante geschachtelter Transaktionen auch die „geschlossene" genannt.

Offen geschachtelte Transaktionen

Geschachtelte Transaktionen in der „geschlossenen" Variante tragen im wesentlichen nichts zur Erhöhung der Parallelität zwischen Anwendungstransaktionen (Intertransaktions-Parallelität) bei, da alle im Laufe der Ausführung von Subtransaktionen erworbenen Sperren bis zum Ende der gesamten Anwendungstransaktionen gehalten werden. Gerade bei langen bzw. interaktiven Transaktionen, wie sie geschachtelte Transaktionen typischerweise sind, ist dies aber ein kritischer Punkt. Im Beispiel der „Urlaubsbuchung" etwa würde eine Sperre auf einem Zähler für die Anzahl freier Plätze eines bestimmten Fluges alle anderen Anwendungstransaktionen, die diesen Flug buchen wollen, blockieren - und zwar wegen des stattfindenden Benutzerdialogs u.U. sehr lange. Ein Ansatz, solche Blockierungen weitgehend zu vermeiden, bzw. erheblich zu verkürzen, besteht darin, zwar nach wie vor parallele Subtransaktionen untereinander zu isolieren, aber die erworbenen Sperren jeweils beim Ende einer Subtransaktion freizugeben und damit die strenge Isolation gegenüber anderen Anwendungstransaktionen fallenzulassen. Unmittelbar nach Abschluß der Flugbuchung könnten dann bereits andere „Urlaubsbuchungen" auf diese Flugdaten zugreifen, selbst wenn die zugehörige Anwendungstransaktion noch im Gang ist. Wegen der vorzeitigen Sichtbarkeit von Änderungen wird diese Variante als die Methode der „offen geschachtelten Transaktion" bezeichnet.

Zwei schwerwiegende Probleme sind bei diesem Ansatz zu lösen. Zum einen können beendete Subtransaktionen immer noch durch den Abbruch eines Vorfahren zurückgesetzt werden. Da aber inzwischen parallele Anwendungstransaktionen auf der Grundlage der vorzeitig freigegebenen Änderungen weitere Modifikationen durchgeführt haben könnten, scheint eine Lawine kaskadenartiger „Rückrufaktionen" unvermeidlich. Die Lösung des Problems besteht darin, an Stelle herkömmlicher zustandsorientierter „Recovery"-Methoden für jede bereits beendete zurückzusetzende Subtransaktion eine weitere Subtransaktion zu starten, die die erfolgten Änderungen kompensiert. Eine Flugreservierung wird z.B. durch eine Stornierung wieder aus der Welt geschafft, und solche inverse Aktionen bzw. Kompensations-Subtransaktionen sind - bis auf wenige Ausnahmen mit irreversiblen Effekten - in der Regel immer möglich.

Das zweite Problem der offen geschachtelten Transaktionen ist die vermeintliche Aufgabe der Serialisierbarkeit als Korrekturkriterium, d.h. der Äquivalenz der parallelen Abläufe zum sequentiellen Einbenutzer-Betrieb. Die Lösung dieses Problems besteht in der Anwendung einer semantischen Concurrency-Control-Methode auf die abgeschlossenen Subtransaktionen entsprechenden abstrakten Aktionen, so daß die „abstrakte Serialisierbarkeit" der gesamten offen geschachtelten Transaktionen bzw. die Korrektheit im allgemeineren Sinn sichergestellt ist.

Mehrschichten-Transaktionen

Ein wichtiger Spezialfall der offen geschachtelten Transaktionen, bei dem die Erzeugung von Subtransaktionen durch die Struktur des zugrundeliegenden Systems bestimmt ist, sind „Mehrschichten-Transaktionen". Zugrundegelegt wird eine Schichtenarchitektur, in der einzelne Operationen einer bestimmten Schicht jeweils durch Folgen von Operationen der nächsttieferen Abstraktionsebene implementiert sind. In einer dementsprechenden Mehrschichten-Transaktionen wird für jede Aktion der höheren Schicht eine Subtransaktion auf der jeweils darunterliegenden Implementierungsebene gebildet. Dieses Prinzip wird von Schicht zu Schicht fortgesetzt, so daß alle Basistransaktionen dieselbe Schachtelungstiefe haben. Der Vorteil dieser festen Struktur ist, daß man nun gegenüber dem allgemeinen Konzept der offen geschachtelten Transaktionen vergleichsweise einfach geeignete Protokolle für die Isolation von Anwendungstransaktionen entwickeln kann. Dabei sind Anwendungstransaktionen im allgemeinen „nur" auf dem Abstraktionsniveau der Anwendungsoperationen (d.h. der obersten Schicht) serialisierbar, was jedoch für den Benutzer vollkommen ausreicht und den darunterliegenden Schichten größeren Freiraum für die parallele Ausführung von Subtransaktionen gibt. Eine ausführliche Diskussion der Implementierungsaspekte von Mehrschichten-Transaktionen ist in zu finden.

Literatur

  1. Beeri, C. Schek, H.-J., Weikum, G.: Multi-Level Transaction Management - Theoretical Art of Practical Need? Proc. Int. Conf. Extending Database Technology (Lecture Notes in Computer Sience, Vol. 303). Berlin, Heidelberg, New York: Springer 1988
  2. Gray, J.: The Transaction Concept: Virtues and Limitations. Proc. Int. Conf. on Very Large Data Bases, 1981
  3. Härder, T., Reuter, A.: Principles of transaction-oriented database recovery. ACM Comput. Surv. 15 (4), (1983)
  4. Moss, J.E.B.: Nested Transactions: An Approach to Reliable Distributed Computing, Cambridge: MIT Press 1985
  5. Walter, B.: Nested Transactions with Multiple Commit Points: An Approch to the Structuring of Advanced Database Applications. Proc. Int. Conf. on Very Large Data Bases, 1984
  6. Weikum, G.: Transaktionen in Datenbanksystemen, Bonn: Addison-Wesley, 1988

Autor und Copyright

G. Weikum (TH Darmstadt)

© 1989 Informatik Spektrum, Springer-Verlag Berlin Heidelberg