Transaktionen
Samstag 27. September 2008 von Andreas Vogt
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
Dieser Beitrag wurde erstellt am Samstag 27. September 2008 um 19:08:05 und abgelegt unter VBA Code. Kommentare zu diesen Eintrag im RSS 2.0 Feed. Sie können einen Kommentar schreiben, oder einen Trackback auf Ihrer Seite einrichten.
PDF Version