Transaktionen
Man stelle sich folgendes Szenario vor:
Sie möchten einen Wareneingang verbuchen und danach einen neuen Einkaufs- und Verkaufspreis berechnen. Dazu müssen Sie 2 Datenbankoperationen durchführen. Sie verbuchen die Ware ins Lager und wollen den Einkaufs- und Verkaufspreis in der Artikeltabelle aktualisieren. Wenn bei der zweiten Operation ein Fehler auftaucht, wird zwar der Wareneingang verbucht, aber Einkaufs- und Verkaufspreis werden nicht in die Tabelle geschrieben. Durch solche Vorgänge ist es leicht möglich dass Tabellen inkonsistent werden.
Tritt also nun bei der zweiten Operation ein Fehler auf und eine Fehlerbehandlung greift, so sind Änderungen der ersten Operation bereits geschrieben. Jetzt müssten Sie eine Methode zur Hand haben, mit der sie alle vorherigen und zusammenhängenden Operationen einfach rückgängig machen könnten. In der Fachsprache wird dieser Vorgang ein Rollback genannt. Und diese Methode bietet uns Access in der Form von Transaktionen.
Microsoft Access bzw. die Jet-Engine stellt dafür zumindest schon seit Access 97 ein leistungsstarkes Transaktionenmodel mit entsprechenden Methoden zur Verfügung. Eine Transaktion hat folgende Methoden:
- BeginTrans
- CommitTrans
- Rollback
Zur Verdeutlichung dazu ein Schema:
Transaktionen lassen sich auch problemlos ineinander verschachteln, also wie in unserem Beispiel wenn für die Berechnung des Verkaufspreises eine weitere Funktion aufgerufen wird. Der Trick ist, dass man obiges Schema kopiert und der der Bearbeitungswolke „Datenbank Operationen“ einfügt. Somit können auch Teiloperationen rückgängig gemacht werden. Beim Verschachteln ist zu beachten dass die innerste Operation zuerst, und die äußerste Operation zuletzt ausgeführt wird.
Außerdem muss man bedenken, dass obwohl in einer inneren Transaktion ein Commit ausgeführt wurde, dies durch ein Rollback einer äußeren Transaktion rückgängig gemacht wird.
Codebeispiel für den Einsatz von Transaktionen :
Public Sub BeispielTransaktion() On Error GoTo BeispielTransaktion_Error Dim ws As Workspace Dim db As Database Dim rs As Recordset Dim flag As Boolean Set ws = DBEngine.Workspaces(0) Set db = CurrentDb Set rs = db.OpenRecordset("Select bestand From tabLager Where ProdID = 4711") 'Start der Transaktion ws.BeginTrans flag = true 'Datenbankoperation, also hinzufügen, ändern, löschen rs.Edit rs!bestand = rs!bestand + 500 rs.Update 'Fragen ob gespeichert werden soll If MsgBox("Änderungen übernehmen?", vbYesNo) = vbYes Then 'Datenübernahme ws.CommitTrans Else 'Änderung verwerfen ws.rollback End If Exit_BeispielTransaktion: Exit Sub BeispielTransaktion_Error: MsgBox "Es ist ein Fehler aufgetreten: " & Err.Description if flag then ws.rollback flag = false Resume Exit_BeispielTransaktion End Sub
Es wird zuerst ein Recordset auf die Tabelle tabLager mit dem Kriterium ProduktID = 4711 der Variable rs zugewiesen. Dann erfolgt der Beginn der Transaktion, die Datenbank-Operation und abschließend die Frage ob die Änderung übernommen werden soll. Falls Ja wird die Methode CommitTrans auf die Workspace-Variable angewendet, falls nein, erfolgt der Rollback und nichts wird gespeichert. Zusätzlich sollte man immer in der Fehlerbehandlung ein Rollback auslösen – eine Fehlerbehandlung bei Transaktionen halte ich für unerlässlich. Wichtig ist auch, dass ein Rollback nur dann ausgelöst wird, wenn zuvor auch BeginTrans ausgelöst wurde. Dies wird mit der Boolean Variable Flag abgesichert, erst wenn flag = true ist, wird ein möglicher Rollback ausgelöst.
Um Transaktionen zu verwenden, benötigen Sie zuerst ein Workspace-Objekt. Unter Umständen ist es möglich, dass die Datenbank Transaktionen gar nicht zulässt. Das kann man z.B. vor dem Beginn der Transaktion abfragen mittels:
if Not db.Transaktions then Msgbox "Transaktionen z.Z. nicht möglich" exit sub else ws.BeginTrans End if
Nun kommt es zum Testen der Transaktion. Am einfachsten geht das, indem ein Überlauf verursacht wird. Fügen Sie nach rs.Update folgendes ein:
Dim i As Integer i = 70000
Dies löst den Fehler Überlauf aus, da der Wertebereich einer Integervariable nur bis 65535 reicht. Das Ausführen der Prozedur zeigt, dass der Fehler „Überlauf“ angezeigt wird und die Datenbank-Operation nicht ausgeführt wird.
Transaktionen sollten überall dort eingesetzt werden, wo im Fehlerfalle eine Datenbankoperation nicht durchgeführt werden soll ober, wo das Speichern von Dateneingaben bestätigt werden soll. Dies ist auch vor allem dann ratsam, wenn man eine Batch-Verarbeitung hat, also eine Reihe aufeinander folgender Datenbankoperationen.
AV 2008