Transaktionen

By , 27. September 2008

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:Ablauf einer Transaktion

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

Leave a Reply

You must be logged in to post a comment.

OfficeFolders theme by Themocracy