TN068:执行事务与Microsoft Access 7 ODBC驱动程序
备注
以下技术声明,则它在联机文档,首先包括了不更新。因此,某些过程和主题可能已过时或不正确。有关最新信息,建议您搜索议题在联机文档的索引。
此说明描述了如何执行事务,在使用 MFC ODBC 数据库类时,以及 Microsoft ODBC 驱动程序包括桌面的 Microsoft Access 7.0 ODBC 驱动程序打包 3.0 版。
概述
如果您的数据库应用程序执行事务,则必须小心调用 CDatabase::BeginTrans 和 CRecordset::Open 以正确的顺序在您的应用程序。 Microsoft Access 7.0 驱动程序使用 Microsoft Jet 数据库引擎,并且, Jet 要求您的应用程序不会开始在有一个打开游标的所有数据库的事务。 对于 MFC ODBC 数据库类,一个打开的光标相当于在中打开 CRecordset 对象。
如果在调用 BeginTrans之前打开记录集,您可能不会任何错误消息。 但是,所有记录集更新您的应用程序会成为永久性在调用 CRecordset::Update后,更新,以不会通过调用 回滚回滚。 若要避免此问题,必须先调用 BeginTrans 然后打开记录集。
MFC 检查光标、提交和回滚行为的功能的驱动程序。 类 CDatabase 在中打开 CRecordset 对象提供两个成员函数, GetCursorCommitBehavior 和 GetCursorRollbackBehavior,请确保所有事务的影响。 对 Microsoft Access 7.0 ODBC 驱动程序,,因为访问驱动程序不支持游标保存,这些成员函数返回 SQL_CB_CLOSE 。 因此,您必须在调用之后 CommitTrans 或 回滚 操作的 CRecordset::Requery 。
当需要依次时执行多个事务中,不能在第一个事务后调用 Requery 然后启动下一个。 ,在下调用 BeginTrans 为了满足喷气机的要求之前,必须关闭记录集。 此方法声明描述处理此情况两个方法:
关闭在每 CommitTrans 或 回滚 操作之后的记录集。
使用 ODBC API 函数 SQLFreeStmt。
结束位置为每个 CommitTrans 或回滚操作后的记录集
在开始事务之前,请确保记录集对象已关闭。 在调用 BeginTrans后,请调用记录集的 打开 成员函数。 关闭在调用 CommitTrans 或 回滚后的记录集。 请注意重复打开和关闭记录集可以降低应用程序的性能。
使用 SQLFreeStmt
也可以使用 ODBC API 函数 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,可以调用开始下一个事务,在提交或回滚第一个之后。 编写这些功能,执行以下步骤:
复制 CRecordset::Requery( ) 的代码对新功能。
添加下行,在对 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 或 回滚 操作后关闭记录集。