Compartilhar via


TN068: Executar transações com o Driver ODBC do Microsoft Access 7

ObservaçãoObservação

A seguinte nota técnica não foi atualizada desde que foi incluída pela primeira vez na documentação online.Como resultado, alguns procedimentos e tópicos podem estar desatualizado ou incorreto.As informações mais recentes, é recomendável que você procure o tópico de interesse no índice de documentação on-line.

Esta nota descreve como realizar transações quando usando as classes de banco de dados ODBC do MFC e o driver ODBC do Microsoft Access 7.0 incluída na Microsoft ODBC Desktop Driver Pack versão 3.0.

Visão Geral

Se seu aplicativo de banco de dados executa transações, você deve ter cuidado para chamar CDatabase::BeginTrans e CRecordset::Open na seqüência correta em seu aplicativo.O driver do Microsoft Access 7.0 usa o mecanismo de banco de dados Microsoft Jet e Jet requer que seu aplicativo não iniciar uma transação no banco de dados tem um cursor aberto.Para classes de banco de dados ODBC do MFC, um cursor aberto equivale a uma abertura CRecordset objeto.

Se você abrir um conjunto de registros antes de chamar BeginTrans, talvez você não veja mensagens de erro.No entanto, qualquer recordset atualiza seu aplicativo faz se tornam permanentes após a chamada de CRecordset::Update, e as atualizações serão não revertidas chamando reversão.Para evitar esse problema, você deve chamar BeginTrans primeiro e depois abra o conjunto de registros.

MFC verifica a funcionalidade do driver para o comportamento de confirmação e reversão do cursor.Classe CDatabase fornece duas funções de membro GetCursorCommitBehavior e GetCursorRollbackBehavior, para determinar o efeito de qualquer transação em seu open CRecordset objeto.Driver ODBC do Microsoft Access 7.0, essas funções de membro retornam SQL_CB_CLOSE porque o driver do Access não oferece suporte a preservação de cursor.Portanto, você deve chamar CRecordset::Requery seguir um CommitTrans ou reversão operação.

Quando você precisar realizar várias transações um após outro, não é possível chamar Requery após a primeira transação e inicie um.Você deve fechar o conjunto de registros antes da próxima chamada para BeginTrans para satisfazer o requisito do Jet.Esta nota técnica descreve dois métodos de tratamento essa situação:

  • Fechando o conjunto de registros após cada CommitTrans ou reversão operação.

  • Usando a função de API ODBC SQLFreeStmt.

Fechando o conjunto de registros após cada CommitTrans ou Rollback operação

Antes de iniciar uma transação, verifique se que o objeto recordset é fechado.Depois de chamar o BeginTrans, chamar o conjunto de registros Abrir função de membro.Fechar o recordset imediatamente após chamar CommitTrans ou reversão.Observe que repetidamente abrindo e fechando o conjunto de registros podem diminuir o desempenho do aplicativo.

Usando SQLFreeStmt

Você também pode usar a função de API ODBC SQLFreeStmt fechar explicitamente o cursor após o término de uma transação.Para iniciar outra transação, chame BeginTrans seguido de CRecordset::Requery.Ao chamar SQLFreeStmt, você deve especificar HSTMT do conjunto de registros como o primeiro parâmetro e SQL_CLOSE como o segundo parâmetro.Este método é mais rápido que fechar e abrir o conjunto de registros no início de cada transação.O código a seguir demonstra como implementar essa técnica:

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( );

Outra maneira de implementar essa técnica é escrever uma nova função, RequeryWithBeginTrans, que você pode chamar para iniciar a próxima transação após você confirmar ou reverter primeiro.Para escrever uma função, siga estas etapas:

  1. Copie o código para (CRecordset::Requery) para a nova função.

  2. Adicione a seguinte linha imediatamente após a chamada para SQLFreeStmt:

    m_pDatabase->BeginTrans( );

Agora você pode chamar esta função entre cada par de transações:

// 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( )
ObservaçãoObservação

Não use essa técnica se você precisar alterar as variáveis de membro do conjunto de registros m_strFilter ou m_strSort entre as transações.Nesse caso, você deve fechar o conjunto de registros após cada CommitTrans ou reversão operação.

Consulte também

Outros recursos

Notas técnicas por número

Notas técnicas por categoria