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::Updatevornehmen, werden jedoch dauerhaft, und die Updates werden nicht durch Aufrufen Rollbackzurü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 GetCursorRollbackBehaviorbestimmt 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 Oder Rollback 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 BeginTransdie 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 SQLFreeStmtmü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, RequeryWithBeginTransnachdem 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:

  1. Kopieren Sie den Code für CRecordset::Requery( ) die neue Funktion.

  2. 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