如何解决多线程对ACCESS数据库记录的操作问题
编号:QA002424
建立日期: 2000年1月11日 最后修改日期:2000年1月13日
所属类别:
Jacky Ng:
操作系统:Windows NT 4.0
编程工具:VC++ 6.0
问题:如何解决多线程对ACCESS数据库记录的增加和删除问题? 具体问题描述如下: 一个对实时性要求非常高的应用系统中,主线程会产生多个子线程同时运行,这些子线程可能都要对同一个ACCESS数据库表进行操作, 为了节省时间,在主线程对ACCESS数据库表创建了CDaoDatabase和CDaoRecordset实例,把CDaoRecordset的指针传给各个子线程, 让子线程通过该CDaoRecordset的指针对表进行更新.这样就不用频繁打开和关闭数据库.但事与愿违:第一个子线程能对数据库操作成功,第二个以后的子线程则总是失败,总是提示:[XXXX]内存不能为[read].即使是第一个子线程彻底完成后(对数据库操作成功),再开始第二个子线程,情况也是这样.问题肯定是出在对数据库操作的部分,因为把对数据库操作的代码注释掉,就不会出现错误。
我也一步步对程序进行跟踪过,各个跟数据库有关的变量都有值,也排除了子线程退出时对一些指针误删除的可能性.我的错误在哪儿? 有没有别的办法代替我这种做法? 各位大虾,请救小弟一命!!!
回答:
DAO itself is not multithreaded, so you can't use the MFC DAO classes in multiple threads. Confine your DAO code to a single thread of execution. Otherwise, look for some other thread-safe database operations.
More ideas regarding this question.
As MFC document stated, the DAO classes are not thread safe. I thought probably finish the coding of your application and have tons of code there already, and don't have enough time to change to another database
classes. So you really want to use DAO in your multi-thread application, there is a solution for you.
And you should remember that this is not a true multithread database access, the Jet will serialize the database function calls. In order to operate the database using DAO in different threads, you have to create its own CDaoDatabase and CDaoRecordset instance in each thread.
1. declare a global instance of critical section
CCriticalSection g_CS;
2. In your thread function
// prevent multi-threads initialize the DAO simultaneously
// it will be unlocked when out of scope
CSingleLock lock(&g_CS, TRUE);
// initialize DAO support of MFC
AfxDaoInit();
// initialize your Dao classes here
CDaoDatabase db;
CMyDaoRecordset rs( &db );
// Open the database and recordset
.....
lock.Unlock(); // free lock to let other threads use Dao
///////////////////////////////////////////
// your database operation goes here
// when you doing this, you don't have to lock other threads
.............................
///////////////////////////////////////////
// After you finish the database operation
// lock again and close your recordset and database
lock.Lock();
rs.Close();
db.Close();
return;
3. In your CApp::ExitInstance(), add these two lines
AfxDaoInit();
AfxDaoTerm();
Hope this will help you.
此问题由Xingong Wu回答。
| |
|
|
| |
|
|