В настоящей записке описывается, как выполнять транзакции при использовании базы данных применяются классы MFC ODBC и драйвер ODBC для Microsoft Access 7.0, включенных в пакет драйверов ODBC Desktop Microsoft версии 3.0.
Обзор
Если приложение базы данных выполняет операции, вы должны тщательно вызывать CDatabase::BeginTrans и CRecordset::Open в правильной последовательности в вашем приложении. Драйвер Microsoft Access 7.0 использует базы данных Microsoft Jet, и Jet требует, что ваше приложение не начать транзакцию на любой базе данных с открытым курсором. Для классов базы данных MFC ODBC открытый курсор будет равнозначно открытый объект CRecordset.
Если открыть набор записей перед вызовом BeginTrans, может не появиться сообщения об ошибках. Однако любые обновления записей приложение делает стать постоянными после вызова метода CRecordset::Updateи обновления будут не откат путем вызова Rollback. Чтобы избежать этой проблемы, необходимо сначала вызвать BeginTrans , а затем открыть набор записей.
MFC проверяет драйвер функциональность для commit и rollback поведение курсора. Класса CDatabase предоставляет две функции-члены, GetCursorCommitBehavior и GetCursorRollbackBehavior, чтобы определить влияние любой сделки на открытый объект CRecordset . Для Microsoft Access 7.0 ODBC драйвера эти функции-члены возвращает SQL_CB_CLOSE , так как драйвер доступа не поддерживает сохранение курсора. Таким образом необходимо вызвать CRecordset::Requery после операции CommitTrans или отката.
Когда вам нужно выполнить несколько операций, один за другим, нельзя вызвать Requery после первой транзакции и запустите следующий. Необходимо закрыть набор записей до следующего вызова BeginTrans с тем чтобы удовлетворять требованию компании Jet. Этот технический записке описываются два метода обработки этой ситуации:
Закрытие набора записей после каждого CommitTrans или операции отката
Прежде чем начать транзакцию, убедитесь, что объект набора записей будет закрыт. После вызова метода BeginTrans, вызовите набор записей функции-члена Open . Закройте набор записей сразу же после вызова метода CommitTrans или Rollback. Обратите внимание, что неоднократно открытия и закрытия набора записей может снизить производительность приложения.
Используя функцию SQLFreeStmt
Можно также использовать функцию ODBC API функцию SQLFreeStmt явным образом закрыть курсор после окончания сделки. Чтобы начать другую транзакцию, вызовите BeginTrans следуют CRecordset::Requery. При вызове функцию SQLFreeStmt, необходимо указать HSTMT набора записей в качестве первого параметра и SQL_CLOSE в качестве второго параметра. Этот метод работает быстрее, чем закрытие и открытие набора записей в начале каждой транзакции. Следующий код показывает, как реализовать этот метод
CMyDatabase дБ;
DB.Открыть ("MYD&ATASOURCE");
CMyRecordset РС (amp дБ);
/ / запустить транзакцию 1 и / / открыть набор записей
DB.BeginTrans ();
RS.(Открытые);
/ / обработки данных
/ / конец транзакции 1
DB.CommitTrans (); / / или отката)
/ / Закрыть курсор
:: Функцию SQLFreeStmt (rs.m_hstmt, SQL_CLOSE);
/ / запустить транзакцию 2
DB.BeginTrans ();
/ / Теперь получить результирующий набор
RS.Повторный запрос ();
/ / обработки данных
/ / конец транзакции 2
DB.CommitTrans ();
RS.Закрыть ();
DB.Закрыть)
Еще один способ реализации этого метода заключается в том, чтобы написать новую функцию, RequeryWithBeginTrans, который можно вызвать для запуска на следующий транзакций после фиксации или отката первый из них. Чтобы написать такую функцию, выполните следующие действия:
m_pDatabase->BeginTrans( );Теперь можно вызвать эту функцию между каждой парой сделок:
/ / запустить транзакцию 1 и / / открыть набор записей
DB.Begi&nTrans ();
RS.(Открытые);
/ / обработки данных
/ / конец транзакции 1
DB.CommitTrans (); nbsp; / / или отката)
/ / Закрыть курсор, запуск новой транзакции,
/ / и получить результирующий набор
RS.RequeryWithBeginTrans ();
/ / обработки данных
/ / конец транзакции 2
DB.CommitTrans (); / / или отката)
Примечание Не следует использовать этот метод, если вам нужно изменить переменные членов набора записей m_strFilter или m_strSort между транзакциями. В этом случае вы должны закрыть набор записей после каждой операции CommitTrans или отката.
Технические примечания по номеру |nbsp; Технические примечания по категориям