I use in my x64 application the Microsoft Access Database Engine 2010 (part of Microsoft Office 2016) for working with mdb files.
But, current version of Microsoft Access Database Engine 2010 (OLEDB provider Microsoft.ACE.OLEDB.12.0) have a bug.
This engine crashes in multithread work.
If I create two OLE DB (or ADO DB) connections with this provider in different threads, then one of them will crashed in Mso40UIwin32client.dll
with exception 0xC0000005: Access violation writing location 0x0000000000000000.
Exception stack:
C++ code sample with this error:
#include "stdafx.h"
#include <atlcom.h>
#include <atldbcli.h>
#include <conio.h>
typedef UINT(__stdcall* fnThread)(PVOID);
HANDLE hExitEvent = NULL;
UINT __stdcall DbThread1(IN PVOID context)
{
HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
_ASSERTE(SUCCEEDED(hRes));
CDataSource DataSource; // Data source connection object
while (::WaitForSingleObject(hExitEvent, 0) != WAIT_OBJECT_0)
{
// Open DB connection
ATLTRACE2(atlTraceGeneral, 0, L"DbThread1: Create connection...\n");
hRes = DataSource.OpenFromInitializationString(L"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=\"C:\\Temp\\Index_empty1.mdb\"; Persist Security Info=False;");
_ASSERTE(SUCCEEDED(hRes));
// Close DB connection
DataSource.Close();
ATLTRACE2(atlTraceGeneral, 0, L"DbThread1: Close connection...\n");
Sleep(20);
}
::CoUninitialize();
_endthreadex(0);
return 0;
}
UINT __stdcall DbThread2(IN PVOID context)
{
HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
_ASSERTE(SUCCEEDED(hRes));
CDataSource DataSource; // Data source connection object
while (::WaitForSingleObject(hExitEvent, 0) != WAIT_OBJECT_0)
{
// Open DB connection
ATLTRACE2(atlTraceGeneral, 0, L"DbThread2: Create connection...\n");
hRes = DataSource.OpenFromInitializationString(L"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=\"C:\\Temp\\Index_empty2.mdb\"; Persist Security Info=False;");
_ASSERTE(SUCCEEDED(hRes));
// Close DB connection
DataSource.Close();
ATLTRACE2(atlTraceGeneral, 0, L"DbThread2: Close connection...\n");
Sleep(20);
}
::CoUninitialize();
_endthreadex(0);
return 0;
}
int main()
{
::CoInitializeEx(NULL, COINIT_MULTITHREADED);
hExitEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
const fnThread aPtrs[] = { DbThread1, DbThread2 };
HANDLE hDbThread[_countof(aPtrs)] = { NULL };
for (int nIndex = 0; nIndex < _countof(aPtrs); nIndex++) {
if ((hDbThread[nIndex] = (HANDLE)::_beginthreadex(nullptr, 0, aPtrs[nIndex], nullptr, 0, nullptr)) == NULL)
{
return 1;
}
}
CComVariant varData;
printf("Press any key to exit...");
// Loop until any key struck
while (!_kbhit())
{
for (DWORD i = 0; i < 100; i++)
{
// Test for bug of the OLEDB provider for MS ACCESS 2010.
varData.Clear();
}
Sleep(0);
}
// Request threads to exit
SetEvent(hExitEvent);
// Wait for threads to exit
WaitForMultipleObjects(_countof(hDbThread), hDbThread, TRUE, INFINITE);
for (auto& h : hDbThread) {
CloseHandle(h);
}
CloseHandle(hExitEvent);
::CoUninitialize();
return 0;
}
You should build this sample for x64 platform with Visual C++ 2013/2015. Similar bug I found at MS forum. Can anybody help me?
We too have encountered this issue in a multi-threaded VB.Net (Framework v4.5.2) service application. After much testing, the only way we found to resolve this was to either use a single thread or turn off connection pooling (using OLE DB Services=-2). In the end we have gone with the latter as we needed the system to be able to process requests in parallel.
FYI, the version of Office 2016 I have installed does not include this driver (hence why our program passed any kind of basic testing) but it was included with the version of Office 2016 that our customer installed. So far I have checked "Microsoft Office Professional Plus 2016" (from both MSDN and MS Partner Network) and "Microsoft Office 365 ProPlus" and none of them appear to come with the Microsoft.ACE.OLEDB.12.0 OLEDB provider. Also, as far as I can see, the only version of the Microsoft Access Database Engine 2010 Redistributable available to download is SP2 (released 22/07/2013) so it is hard to get this tested in a development environment!
User contributions licensed under CC BY-SA 3.0