DAO multi-threading tips
Looks like DAO 3.5 has some support for multi-threading.
As stated by the MFC 4.2 documentation, the Dao database classes are not thread-safe, and that is indeed true.
I recently developed a server application the uses IO completion ports, which by nature, are using a number of threads. Because of that, I had to figure out a way to use DAO in different threads simultaneously. Here is how I did it:
//
// used a global critical section to prevent multiple threads initializing
// the Dao database simultaneous.
//
CCriticalSection cs;
//
// Some thread function
// (In my server app, 4 thread using this function is started)
//
UINT MyThreadFunc (LPVOID pParam)
{
CSingleLock lock(&cs, TRUE);
//
// Initialize MFC Dao support
//
AfxDaoInit();
CDaoDatabase db;
CSomeDaoRecordset set(&db);
//
// Open the database and recordset.
//
try
{
db.Open(_T("database.mdb"));
set.Open(dbOpenTable);
set.SetCurrentIndex(_T("PrimaryKey"));
}
catch(CException* pe)
{
pe->ReportError();
pe->Delete();
return 0;
}
//
// Allow other threads to initialize Dao
//
lock.Unlock();
//
// OK the database and recordset is now open
//
while( bRunThisThread )
{
//
// NOTE: You do NOT need to lock out other threads vhile calling
// database functions here.
//
WaitForClientRequest();
ParseRequest();
DoDatabaseIO();
}
//
// Now, lock the critical section again
//
lock.Lock();
//
// Close recordset and database.
rs.Close();
db.Close();
// IMPORTANT: do NOT call AfxDaoTerm() !!!!
return 0;
}
Now, when your application terminates, it will generate a protection error. To prevent that modify your CMyApp::ExitInstance().
int CMyApp::ExitInstance()
{
//
// Insert your own cleanup code here
//
AfxDaoInit();
AfxDaoTerm();
return m_msgCur.wParam;
}
Notes:
7 The MFC documentation says the you need to call AfxBeginThread to start worker threads, but this is not necessary at all times, it depends on what your doing in your thread function. (I use both AfxBeginThread() and ::CreateThread()).
7 I call AfxBeginThread() in my main InitInstance() function, but I am not really sure if this is necessary. Of course, you should do it if you need to access the database from your main thread.
7 You will not gain true multithreaded access to the database functions. Jet 3.5 serializes the function calls, but the threads do not have to worry about that.
Known problems:
1. I have discovered that this approach can sometimes prevent other applications from starting, like MS Word 97, they simply hang, but when i shutdown my multithreaded Dao app, they continues as though nothing has happened ?????
2. My spelling :-)
3. ::CoInitialize() will be called for every call to AfxDaoInit(), and will not all be matched by a call to :: ::CoUninitialize(), but i hope the Windows will clean up the mess.

Comments
No Different Threads---
Posted by Legacy on 08/01/2003 12:00amOriginally posted by: Siddharth
I put this solution in my project and its seem to work for first thread and if i invoke another thread containing AfxDaoInit from the first thread its giving runtime error
ReplyAbnormal Programme Termination but its running perfectly alright on Win2000 server but not on winME
Danke
Posted by Legacy on 02/18/2003 12:00amOriginally posted by: jan
thank you for this elegant and usful piece of code.
Replyprovide good online coaching
Posted by Legacy on 12/24/2002 12:00amOriginally posted by: phani bhushan reddy
respected sir,
Replyhere iam happy to get this option , to share my views/problems with you. sir i found one problem while i was using brain bench site.i didnot know about com and dcom.
i want to know about that if any chances are there for it
please specify through mail .
if my request is not glad to receive please excuse me.
thanking you,
i hope the best
TH
Posted by Legacy on 08/09/2002 12:00amOriginally posted by: Gabor M�lyi
Thank You!
Your's programs great, and able piece of my work.
Gabor
ReplyThank you
Posted by Legacy on 02/25/2002 12:00amOriginally posted by: Chetan
Your article saved me from lots of Multi threading issues I encountered due to DAO.
Thanks again.
ReplyMuchos Gracias!
Posted by Legacy on 12/28/1999 12:00amOriginally posted by: Zenon
After racking my brain for hours on end, I finally consulted CodeGuru, and voil�, the answer was there waiting for me.
Many thanks to John Bundgaard who just made my life a whole lot easier.
ReplyRestart IDE
Posted by Legacy on 05/17/1999 12:00amOriginally posted by: James Johnston
Have you restarted the Visual Studio IDE?
ReplyUnlock the lock?
Posted by Legacy on 01/15/1999 12:00amOriginally posted by: Morten Tor Nielsen
When the thread is done with the database the database objects are closed.
That piece of code is executed in a monitor (the entrance is the lock.Lock() statement) but don't you need a lock.Unlock() statement after the closing of the DAO objects (or does the CSingleLock unlock when you exit scope??)
Otherwise thanks for the tip - VERY Very helpfull
Morten
ReplyMutli Threaded DAO
Posted by Legacy on 01/13/1999 12:00amOriginally posted by: Jeff Miller
A client had a problem with the DAO code crashing when used in multiple threads. There were several million lines of code. To touch the minimal amount of code, I came up with a way to force all of the DAO calls to go through the GUI thread. If anyone is interested in this approach, I can post the code.
ReplyStop other programs starting until Database program terminated
Posted by Legacy on 11/18/1998 12:00amOriginally posted by: Steve Westgate
ReplyLoading, Please Wait ...