CRecordset::GetFieldValue c++ 多线程中的异常 "GetFieldValue operation failed on field ..."
CRecordset::GetFieldValue exception "GetFieldValue operation failed on field ..." in c++ multithreading
我在使用 CRecordset 实例调用 GetFieldValue() 函数时遇到异常 "GetFieldValue operation failed on field ..."。它适用于单线程,但仅在多线程时才会导致错误。正在使用以下语句。有帮助吗?
打开数据库:
CDatabase dbhandle;
dbhandle.OpenEx(dsn.c_str(), CDatabase::noOdbcDialog);
要执行查询并打开记录集:
boost::shared_ptr<CRecordset> recordset(new CRecordset( &dbhandle ));
recordset->Open(AFX_DB_USE_DEFAULT_TYPE, selectquery.c_str(), CRecordset::readOnly | CRecordset::executeDirect);
读取结果:
recordset->GetFieldValue(fieldname.c_str(), value, SQL_C_CHAR);
确定问题并修复它。出现异常是因为两个不同的线程试图访问同一个 CDatabase
句柄。 CDatabase
目前不是线程安全的。
解决方案是使用 mutex
实现应用程序级锁定。为 CDatabase
编写适配器 class 并为所有操作执行 lock/unlock。
// Define lock variable as instance
boost::mutex database_lock;
// Add the below line in each function which access database
boost::unique_lock<boost::mutex> lock(database_lock);
访问 http://www.boost.org/doc/libs/1_41_0/doc/html/thread/synchronization.html 了解有关锁定的更多信息。
我在使用 CRecordset 实例调用 GetFieldValue() 函数时遇到异常 "GetFieldValue operation failed on field ..."。它适用于单线程,但仅在多线程时才会导致错误。正在使用以下语句。有帮助吗?
打开数据库:
CDatabase dbhandle;
dbhandle.OpenEx(dsn.c_str(), CDatabase::noOdbcDialog);
要执行查询并打开记录集:
boost::shared_ptr<CRecordset> recordset(new CRecordset( &dbhandle ));
recordset->Open(AFX_DB_USE_DEFAULT_TYPE, selectquery.c_str(), CRecordset::readOnly | CRecordset::executeDirect);
读取结果:
recordset->GetFieldValue(fieldname.c_str(), value, SQL_C_CHAR);
确定问题并修复它。出现异常是因为两个不同的线程试图访问同一个 CDatabase
句柄。 CDatabase
目前不是线程安全的。
解决方案是使用 mutex
实现应用程序级锁定。为 CDatabase
编写适配器 class 并为所有操作执行 lock/unlock。
// Define lock variable as instance
boost::mutex database_lock;
// Add the below line in each function which access database
boost::unique_lock<boost::mutex> lock(database_lock);
访问 http://www.boost.org/doc/libs/1_41_0/doc/html/thread/synchronization.html 了解有关锁定的更多信息。