在2个不同的连接上执行的ADO插入和删除会导致错误

时间:2011-12-27 20:54:38

标签: multithreading visual-c++ ado jet

问题:
我看到两个线程中每个线程都有E_FAIL和数据库损坏的组合,每个线程都有自己的连接打开到Jet 4.0 mdb。

情境:
我有一个申请表:

线程1是主线程。它使用提供程序“Microsoft.Jet.OLEDB.4.0”向Jet 4.0 mdb打开ADO连接。它负责通过

将数据插入位于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-&gt; Delete()。两者都已改为使用Conn-&gt; Execute(...)
  • 我们的下一个想法是转向实现一个关键部分,并在线程之间传递。这看起来很激烈,因为看起来ADO应该能够处理来自多个连接的请求。
  • 我熟悉Jet 4.0的页面级锁定大小为4k,我想知道我们是否正在点击它,并且需要切换到记录级锁定。
  • 我会接受别人的想法,尽管他们可能很激动......

编辑1:
刚尝试将两个 - &gt; Execute()包装在一个关键部分;偶尔也会从DELETE FROM中设置E_FAIL。

编辑2:
还尝试在检索主键值后立即关闭记录集(代码已更新以反映更改)

1 个答案:

答案 0 :(得分:1)

您收到的是否有更具描述性的错误消息?我的猜测是并发违规。您可以尝试关闭并释放“pADORstTable”,因为两个记录集都在同一个表上运行。我也会在EOF之后关闭并释放“pADORst”。