Questa nota viene descritto come eseguire transazioni quando si utilizzano le classi di database ODBC MFC e il driver ODBC di Microsoft Access 7.0 incluso nella versione Microsoft ODBC Desktop Driver Pack 3.0.
Panoramica
Se la vostra applicazione di database esegue transazioni, è necessario essere attenti a chiamare CDatabase::BeginTrans e CRecordset:: Open nella sequenza corretta nell'applicazione. Il driver di Microsoft Access 7.0 utilizza il motore di database Microsoft Jet e Jet richiede che l'applicazione non iniziare una transazione in un database che dispone di un cursore aperto. Per le classi di database ODBC MFC, un cursore aperto equivale a un oggetto CRecordset aperto.
Se si apre un recordset prima di chiamare BeginTrans, non si possono vedere eventuali messaggi di errore. Tuttavia, per gli aggiornamenti recordset che l'applicazione fa diventare permanente dopo la chiamata possibilee gli aggiornamenti saranno non rollback chiamando Rollback. Per evitare questo problema, è necessario chiamare BeginTrans prima e quindi aprire il recordset.
MFC controlla la funzionalità del driver per il comportamento del cursore commit e rollback. Classe CDatabase fornisce due funzioni membro, GetCursorCommitBehavior e GetCursorRollbackBehavior, per determinare l'effetto di qualsiasi transazione sull'oggetto CRecordset aperto. Per il driver ODBC di Microsoft Access 7.0, queste funzioni membro restituiranno SQL_CB_CLOSE perché il driver di accesso non supporta la preservazione del cursore. Pertanto, è necessario chiamare CRecordset:: Requery dopo un'operazione di CommitTrans o Rollback.
Quando è necessario eseguire transazioni multiple uno dopo l'altro, non può chiamare Requery dopo la prima transazione e poi iniziare a quello successivo. È necessario chiudere il recordset prima della prossima chiamata a BeginTrans al fine di soddisfare il requisito del getto. Questa nota tecnica descrive due metodi di gestire questa situazione:
Chiudendo l'oggetto Recordset dopo ogni operazione di Rollback o CommitTrans
Prima di iniziare una transazione, assicurarsi che l'oggetto recordset è chiuso. Dopo la chiamata BeginTrans, chiamare la funzione membro Open del recordset. Chiudere il recordset immediatamente dopo la chiamata CommitTrans o Rollback. Si noti che ripetutamente di apertura e chiusura del recordset può rallentare le prestazioni di un'applicazione.
Utilizzo di SQLFreeStmt
È anche possibile utilizzare la funzione API ODBC SQLFreeStmt a chiudere in modo esplicito il cursore dopo la conclusione di una transazione. Per iniziare un'altra transazione, chiamare BeginTrans seguita da CRecordset:: Requery. Quando si chiama SQLFreeStmt, è necessario specificare HSTMT del recordset come primo parametro e SQL_CLOSE come secondo parametro. Questo metodo è più veloce di chiusura e apertura dell'oggetto recordset all'inizio di ogni transazione. Il codice riportato di seguito viene illustrato come implementare questa tecnica
Db CMyDatabase;
DB.&Aperto ("MYDATASOURCE");
CMyRecordset rs (amp; db);
/ / avvia la transazione 1 e / / aperto il recordset
DB.BeginTrans ();
RS.Open ();
/ / modificare i dati
/ / end transazione 1
DB.CommitTrans (); / / o Rollback)
/ / chiudere il cursore
:: SQLFreeStmt (rs.m_hstmt, SQL_CLOSE);
/ / avvia la transazione 2
DB.BeginTrans ();
/ / ora ottenere il set di risultati
RS.Ripetere la query ();
/ / modificare i dati
/ / end transazione 2
DB.CommitTrans ();
RS.Close ();
DB.(Chiudi)
Un altro modo per implementare questa tecnica è quello di scrivere una nuova funzione, RequeryWithBeginTrans, che si può chiamare per avviare il prossimo transazione dopo eseguire il commit o rollback quello primo. Per scrivere tale funzione, effettuare le seguenti operazioni:
m_pDatabase-gt;BeginTrans( );Ora è possibile chiamare questa funzione tra ogni coppia di transazioni:
/ / avvia la tra&nsazione 1 e / / aperto il recordset
DB.BeginTrans ();
RS.Open ();
/ / modificare i dati
/ / end transazione 1
DB.CommitTrans (dll); nbsp; / / o Rollback)
/ / chiudere il cursore, avvia la nuova transazione,
/ / e ottenere il set di risultati
RS.RequeryWithBeginTrans ();
/ / modificare i dati
/ / end transazione 2
DB.CommitTrans (); / / o Rollback)
&Notanbsp; Non utilizzare questa tecnica se è necessario modificare il recordset membri variabili m_strFilter o m_strSort tra le transazioni. In tal caso, si dovrebbe chiudere il recordset dopo ogni operazione di CommitTrans o Rollback.
&Note tecniche per numero |nbsp; Note tecniche per la categoria