TN068: Ausführen von Transaktionen mit dem Microsoft Access 7 ODBC-Treiber
Hinweis
Der folgende technische Hinweis wurde seit dem ersten Erscheinen in der Onlinedokumentation nicht aktualisiert. Daher können einige Verfahren und Themen veraltet oder falsch sein. Um aktuelle Informationen zu erhalten, wird empfohlen, das gewünschte Thema im Index der Onlinedokumentation zu suchen.
In diesem Hinweis wird beschrieben, wie Transaktionen bei Verwendung der MFC ODBC-Datenbankklassen und des in der Version 3.0 von Microsoft ODBC Desktop Driver Pack enthaltenen Microsoft Access 7.0-ODBC-Treibertreibers ausgeführt werden.
Überblick
Wenn Ihre Datenbankanwendung Transaktionen ausführt, müssen Sie darauf achten, dass Sie in Ihrer Anwendung die richtige Reihenfolge aufrufen CDatabase::BeginTrans
und CRecordset::Open
in der richtigen Reihenfolge ausführen. Der Microsoft Access 7.0-Treiber verwendet das Microsoft Jet-Datenbankmodul, und Jet erfordert, dass Ihre Anwendung keine Transaktion mit einer Datenbank beginnt, die einen geöffneten Cursor enthält. Für die MFC ODBC-Datenbankklassen entspricht ein geöffneter Cursor einem geöffneten CRecordset
Objekt.
Wenn Sie ein Recordset vor dem Aufrufen BeginTrans
öffnen, werden möglicherweise keine Fehlermeldungen angezeigt. Alle Recordsetaktualisierungen, die Ihre Anwendung nach dem Aufrufen CRecordset::Update
vornehmen, werden jedoch dauerhaft, und die Updates werden nicht durch Aufrufen Rollback
zurückgesetzt. Um dieses Problem zu vermeiden, müssen Sie zuerst aufrufen BeginTrans
und dann das Recordset öffnen.
MFC überprüft die Treiberfunktionalität auf Cursor-Commit- und Rollbackverhalten. Die Klasse CDatabase
stellt zwei Memberfunktionen bereit und GetCursorCommitBehavior
GetCursorRollbackBehavior
bestimmt die Auswirkungen einer Transaktion auf das geöffnete CRecordset
Objekt. Für den MICROSOFT Access 7.0 ODBC-Treiber geben diese Memberfunktionen zurück SQL_CB_CLOSE
, da der Access-Treiber die Cursorkonservierung nicht unterstützt. Daher müssen Sie nach einem Vorgang oder Rollback
einem CommitTrans
Vorgang aufrufenCRecordset::Requery
.
Wenn Sie mehrere Transaktionen nacheinander ausführen müssen, können Sie nach der ersten Transaktion nicht mehr aufrufen Requery
und dann die nächste transaktion starten. Sie müssen das Recordset vor dem nächsten Aufruf BeginTrans
schließen, um die Anforderung von Jet zu erfüllen. In diesem technischen Hinweis werden zwei Methoden zur Behandlung dieser Situation beschrieben:
Schließen des Recordsets nach jedem
CommitTrans
OderRollback
Vorgang.Verwenden der ODBC-API-Funktion
SQLFreeStmt
.
Schließen des Recordsets nach jedem CommitTrans- oder Rollbackvorgang
Stellen Sie vor dem Starten einer Transaktion sicher, dass das Recordset-Objekt geschlossen ist. Rufen Sie nach dem Aufrufen BeginTrans
die Memberfunktion des Open
Recordsets auf. Schließen Sie das Recordset unmittelbar nach dem Aufrufen CommitTrans
oder Rollback
. Beachten Sie, dass das Öffnen und Schließen des Recordsets die Leistung einer Anwendung verlangsamen kann.
Verwenden von SQLFreeStmt
Sie können auch die ODBC-API-Funktion SQLFreeStmt
verwenden, um den Cursor nach dem Beenden einer Transaktion explizit zu schließen. Um eine weitere Transaktion zu starten, rufen Sie BeginTrans
gefolgt von CRecordset::Requery
. Beim Aufrufen SQLFreeStmt
müssen Sie das HSTMT des Recordsets als ersten Parameter angeben und als zweiten Parameter SQL_CLOSE . Diese Methode ist schneller als das Schließen und Öffnen des Recordsets zu Beginn jeder Transaktion. Der folgende Code veranschaulicht die Implementierung dieser Technik:
CMyDatabase db;
db.Open("MYDATASOURCE");
CMyRecordset rs(&db);
// start transaction 1 and
// open the recordset
db.BeginTrans();
rs.Open();
// manipulate data
// end transaction 1
db.CommitTrans(); // or Rollback()
// close the cursor
::SQLFreeStmt(rs.m_hstmt, SQL_CLOSE);
// start transaction 2
db.BeginTrans();
// now get the result set
rs.Requery();
// manipulate data
// end transaction 2
db.CommitTrans();
rs.Close();
db.Close();
Eine weitere Möglichkeit zum Implementieren dieser Technik besteht darin, eine neue Funktion zu schreiben, die Sie aufrufen können, um die nächste Transaktion zu starten, RequeryWithBeginTrans
nachdem Sie den Commit oder das Rollback des ersten vorgangs ausgeführt haben. Führen Sie die folgenden Schritte aus, um eine solche Funktion zu schreiben:
Kopieren Sie den Code für
CRecordset::Requery( )
die neue Funktion.Fügen Sie die folgende Zeile unmittelbar nach dem Anruf hinzu
SQLFreeStmt
:m_pDatabase->BeginTrans( );
Jetzt können Sie diese Funktion zwischen jedem Transaktionspaar aufrufen:
// start transaction 1 and
// open the recordset
db.BeginTrans();
rs.Open();
// manipulate data
// end transaction 1
db.CommitTrans(); // or Rollback()
// close the cursor, start new transaction,
// and get the result set
rs.RequeryWithBeginTrans();
// manipulate data
// end transaction 2
db.CommitTrans(); // or Rollback()
Hinweis
Verwenden Sie diese Technik nicht, wenn Sie die Recordsetelementvariablen m_strFilter oder m_strSort zwischen Transaktionen ändern müssen. In diesem Fall sollten Sie das Recordset nach jedem CommitTrans
Vorgang Rollback
schließen.
Siehe auch
Technische Hinweise – nach Nummern geordnet
Technische Hinweise – nach Kategorien geordnet