Stell dir eine Überweisung vor: Von Konto A wird abgebucht, auf Konto B gutgeschrieben. Bricht der Vorgang nach dem Abbuchen ab, ist Geld verschwunden. Genau solche zusammenhängenden Änderungen sicherst du mit Transaktionen ab — sie gelten nach dem Prinzip Alles-oder-nichts: Entweder alle Schritte greifen, oder keiner.
Warum Transaktionen?
Ohne Transaktion wird jede Änderung sofort einzeln geschrieben. Kracht dein Code mitten in einer Reihe von Updates, bleibt die Datenbank in einem halbfertigen, inkonsistenten Zustand. Eine Transaktion klammert mehrere Operationen zusammen:
BeginTrans– Transaktion starten,CommitTrans– alle Änderungen endgültig bestätigen,Rollback– im Fehlerfall alles zurücknehmen, als wäre nichts geschehen.
Der Workspace in DAO
In DAO laufen Transaktionen über das Workspace-Objekt, nicht direkt über die
Datenbank. Den Standard-Workspace holst du dir über DBEngine.Workspaces(0):
Dim ws As DAO.Workspace
Dim db As DAO.Database
Set ws = DBEngine.Workspaces(0)
Set db = ws.Databases(0) ' oder: Set db = CurrentDb
Wichtig:
BeginTrans/CommitTrans/Rollbacksind Methoden des Workspace. Die betroffenen Recordsets oderExecute-Aufrufe müssen zu einer Datenbank desselben Workspace gehören, sonst umschließt die Transaktion sie nicht.
Ein vollständiges Beispiel
Hier die klassische Überweisung: zwei zusammenhängende Updates, die nur gemeinsam
gelten dürfen. Der On Error-Handler sorgt dafür, dass bei jedem Fehler ein
Rollback erfolgt:
Public Sub Ueberweisung(vonKonto As Long, nachKonto As Long, betrag As Currency)
Dim ws As DAO.Workspace
Dim db As DAO.Database
Dim inTrans As Boolean
Set ws = DBEngine.Workspaces(0)
Set db = CurrentDb
On Error GoTo Fehler
ws.BeginTrans
inTrans = True
' 1. Abbuchen
db.Execute "UPDATE Konten SET Saldo = Saldo - " & betrag & _
" WHERE KontoID = " & vonKonto, dbFailOnError
' 2. Gutschreiben
db.Execute "UPDATE Konten SET Saldo = Saldo + " & betrag & _
" WHERE KontoID = " & nachKonto, dbFailOnError
ws.CommitTrans ' beide Schritte gemeinsam bestätigen
inTrans = False
Set db = Nothing
Set ws = Nothing
Exit Sub
Fehler:
If inTrans Then ws.Rollback ' nur zurückrollen, wenn Trans läuft
Set db = Nothing
Set ws = Nothing
MsgBox "Überweisung fehlgeschlagen: " & Err.Description, vbCritical
End Sub
Das
dbFailOnErrorbeiExecuteist entscheidend: Ohne diese Option schluckt DAO Fehler bei betroffenen Datensätzen still, dein Handler springt gar nicht an — und derRollbackbleibt aus.
Warum das Flag inTrans?
Ein Rollback ohne laufende Transaktion löst selbst einen Fehler aus. Springt dein
Code in den Handler, bevor BeginTrans lief (oder nachdem CommitTrans schon
durch ist), darfst du nicht zurückrollen. Das Boolean inTrans merkt sich den
Zustand sauber.
Performance-Vorteil bei Massen-Updates
Transaktionen sind nicht nur für die Konsistenz da — sie beschleunigen viele
Einzeländerungen oft drastisch. Ohne Transaktion schreibt die Datenbank-Engine
nach jeder Änderung auf die Platte. In einer Transaktion sammelt sie die Änderungen
und schreibt sie gebündelt beim CommitTrans:
Public Sub PreiseErhoehen()
Dim ws As DAO.Workspace
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set ws = DBEngine.Workspaces(0)
Set db = CurrentDb
Set rs = db.OpenRecordset("Artikel", dbOpenDynaset)
On Error GoTo Fehler
ws.BeginTrans
Do Until rs.EOF
rs.Edit
rs!Preis = rs!Preis * 1.05 ' 5 % Aufschlag
rs.Update
rs.MoveNext
Loop
ws.CommitTrans ' alles auf einmal schreiben
rs.Close
Set rs = Nothing: Set db = Nothing: Set ws = Nothing
Exit Sub
Fehler:
ws.Rollback
If Not rs Is Nothing Then rs.Close
MsgBox "Abgebrochen: " & Err.Description
End Sub
Bei zehntausenden Datensätzen kann das den Unterschied zwischen Minuten und Sekunden ausmachen — als Nebeneffekt ist der Vorgang auch noch abbruchsicher.
Hinweise und Grenzen
- Verschachtelung: Transaktionen lassen sich schachteln (bis zu fünf Ebenen). Ein
äußeres
Rollbacknimmt auch bereits committete innere Transaktionen zurück. - Speicher: Alle Änderungen einer offenen Transaktion werden zwischengepuffert. Extrem große Transaktionen (Millionen Zeilen) können den Puffer sprengen — dann in Blöcken committen.
- Verknüpfte ODBC-Tabellen: Bei per ODBC verknüpften Server-Tabellen greift die DAO-Transaktion nicht immer wie erwartet; dort ist ADO/serverseitige Transaktionssteuerung sicherer.
- Nicht vergessen abzuschließen: Eine offene Transaktion ohne
CommitTransoderRollbackhält Sperren und wird beim Schließen des Workspace verworfen. - DDL: Strukturänderungen (Tabellen anlegen/löschen) sind nicht zuverlässig transaktionsfähig — Transaktionen sind für Datenänderungen (DML) gedacht.
Zusammengefasst
- Transaktionen bündeln mehrere Änderungen nach dem Alles-oder-nichts-Prinzip und verhindern halbfertige, inkonsistente Zustände.
- In DAO über den
Workspace:ws.BeginTrans,ws.CommitTrans,ws.Rollback— die Datenbank muss zum selben Workspace gehören. - Immer mit
On Errorabsichern und im FehlerfallRollback; eininTrans-Flag verhindert einenRollbackohne laufende Transaktion. ExecutemitdbFailOnErrorverwenden, sonst schlägt der Fehler nicht durch und der Rollback bleibt aus.- Für Massen-Updates bringen Transaktionen einen großen Geschwindigkeitsvorteil; Grenzen bei Puffergröße, ODBC-Tabellen und DDL beachten.