Поделиться через


TN068: Выполнение транзакций с драйвером ODBC для Microsoft Access 7

ПримечаниеПримечание

Следующая техническая заметка не была обновлена со времени сначала была включена в подключенной документации.В результате некоторые процедуры и разделы могут оказаться устаревшей или неверны.Последние новости, рекомендуется поиск раздела процента в подключенном индексу документации.

Эта заметка описание выполнения транзакции при использовании классов базы данных MFC ODBC и драйвером ODBC для Microsoft Access 7,0, включенное в драйвере рабочего стола упаковывает Microsoft ODBC версии 3.0.

Общие сведения

Если приложение базы данных выполняет транзакции, необходимо соблюдать осторожность при вызове CDatabase::BeginTrans и CRecordset::Open в правильной последовательности в приложении.Драйвер Microsoft Access 7,0 использует ядро СУБД Microsoft jet и jet требует, что приложение начинает транзакцию в любой базе данных, которая содержит открытый курсор.Для классов базы данных MFC ODBC, открытый курсор равносильно открыть CRecordset объект.

При открытии набора записей перед вызовом BeginTrans, то нельзя увидеть все сообщения об ошибках.Однако любой набор записей обновляет приложение выполняет о постоянно после вызова CRecordset::Update и обновления не будут откаченны путем вызова Откат.Чтобы избежать этой проблемы, необходимо вызвать BeginTrans в первую очередь, а затем открытия набора записей.

MFC проверяет функциональность курсора драйвера для фиксации и отката расширения функциональности.Класс CDatabase содержит функцию-член, GetCursorCommitBehavior 2 и GetCursorRollbackBehavior, для определения влияния любой транзакции в объекте CRecordset открыть.Драйвер ODBC для Microsoft Access 7,0, такие функции-члены возвращают SQL_CB_CLOSE так как драйвер доступа не поддерживает консервацию курсора.Поэтому необходимо вызвать метод CRecordset::Requery вслед за операцией CommitTrans или Откат.

Если требуется выполнить несколько транзакций один за другим, нельзя вызывать Requery после первой транзакции, а затем запустить следующие действия.Необходимо закрыть набор записей, прежде чем следующий вызов BeginTrans для удовлетворения требования для jet.Эта техническая примечание описывает 2 метода обработки этой ситуации:

  • Набор записей " закрыть после каждой операции CommitTrans или Откат.

  • С помощью API-функций ODBC SQLFreeStmt.

Набор записей " закрыть после каждой операции CommitTrans или rollback

Прежде чем начать транзакцию, убедитесь, что объект набора записей закрыт.После вызова BeginTrans, вызовите функцию-член Открыть набора записей.Закройте набор записей сразу после вызова CommitTrans или Откат.Обратите внимание, что повторного открытия и закрытия набор записей может снизить производительность приложения.

Используя функцию SQLFreeStmt

Можно также использовать функции API ODBC SQLFreeStmt, чтобы явно закрыть курсор после завершения транзакции.Для запуска другая транзакция, вызов BeginTrans выполните CRecordset::Requery.При вызове SQLFreeStmt, HSTMT набора записей необходимо указать в качестве первого параметра и SQL_CLOSE в качестве второго параметра.Этот метод быстрее, чем заключение и открытие набора записей в начале каждой транзакции.В следующем примере кода показано, как реализовать этот метод.

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

Другой способ реализации этого метода создать новую функцию, RequeryWithBeginTrans, который можно вызывать для запуска следующая транзакция после фиксации или отката первый из них.Чтобы создать такую функцию, выполните следующие действия:

  1. Скопируйте код для CRecordset::Requery( ) к новой функции.

  2. Добавьте следующую линия сразу после вызова метода SQLFreeStmt:

    m_pDatabase->BeginTrans( );

Теперь можно вызвать эту функцию между каждой парой транзакций:

// 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( )
ПримечаниеПримечание

Не используйте этот метод, если требуется изменять переменные m_strFilter или m_strSort элемента набора записей между транзакциями.В этом случае необходимо закрыть набор записей после каждой операции CommitTrans или Откат.

См. также

Другие ресурсы

Технические замечания по номеру

Технические замечания по категориям