Проблема:
Я вижу комбинацию E_FAIL и повреждения базы данных в каждом из двух потоков, каждый из которых имеет свое собственное соединение, открытое для Jet 4.0 MDB.
Сценарий:
У меня есть приложение, где:
Нить 1 является основной нитью.Он имеет ADO-соединение, открытое для Jet 4.0 mdb, используя провайдера «Microsoft.Jet.OLEDB.4.0».Он отвечает за вставку данных в одну из двух таблиц, расположенных в базе данных mdb, через
hr = pADOConn->Execute("INSERT INTO ...", NULL, adCmdText|adExecuteNoRecords, NULL);
// occasionally returns E_FAIL
Поток 2 является дочерним по отношению к потоку 1. Он также имеет соединение ADO, открытое с точно такой же строкой соединения.Он отвечает за итерацию записей, уже присутствующих в каждой из двух таблиц, «подкачку» каждой строки на сервер и затем удаление строки из таблицы.Это достигается с помощью (сокращенно только для соответствующих частей):
countSQL = "select count(*) from TABLE";
iRecCount = pADORstTable->Open(countSQL, pADOConn2, adOpenKeyset, adLockOptimistic, adCmdText);
for (iRecCtr = 0; iRecCtr < iRecCount; iRecCtr++)
{
// provides the capability to skip records
strSQL = "SELECT TOP 1 * FROM (SELECT TOP " + iSkipRecords +
" * FROM TABLE ORDER BY PriKey DESC)";
pADORst->Open(strSQL, pADOConn2, adOpenKeyset, adLockOptimistic, adCmdText);
pADORst->get_EOF(&vbEOF);
if (vbEOF)
break;
RstPriKey = GetFieldValueForPriKey(pADORst);
pADORst->Close();
pADORst->Release();
// pump record to server
...
// delete record
bstrSQL = "delete from TABLE where PriKey = " + RstPriKey;
hr = pADOConn2->Execute(bstrSQL, NULL, adCmdText|adExecuteNoRecords, NULL);
// occasionally returns E_FAIL
}
Обходные пути:
- Первоначально было закодировано для использованияодиночное соединение, на которое дочернему потоку был передан указатель.С тех пор мы разделили его на два отдельных соединения.
- Код изначально создал набор записей ado для выполнения вставки и использовал базовый набор записей ADO для выполнения pADORst-> Delete ().С тех пор оба были изменены, чтобы использовать Conn-> Execute (...)
- Наша следующая мысль - перейти к реализации критического раздела и передать его между потоками.Это кажется радикальным, поскольку кажется, что ADO должен быть в состоянии обрабатывать запросы, поступающие из нескольких соединений.
- Я знаком с размером блокировки страниц Jet 4,0, и мне интересно, если мыудар по нему, и нужно переключиться на блокировку уровня записи.
- Я буду развлекать чужие мысли, какими бы резкими они ни были ...
Редактировать 1:
Только что попробовал обернуть оба -> Execute () в критическую секцию;по-прежнему время от времени устанавливает E_FAIL из DELETE FROM.
Edit 2:
Также попытался закрыть набор записей сразу после получения значения первичного ключа (код обновлен для отражения изменений)