2011-12-27 34 views
-1

問題:
我看到E_FAIL的每兩個線程,每有一個噴氣4.0 MDB自己的連接打開的組合和數據庫損壞。ADO插入和刪除在2個不同的連接執行導致錯誤

場景:
我有一個應用程序,其中:

線程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-> Delete()。兩者已經被改爲使用Conn-> Execute(...)
  • 我們接下來的想法是轉向實現關鍵部分,並在線程之間傳遞。這看起來很激烈,因爲ADO似乎應該能夠處理來自多個連接的請求。
  • 我熟悉Jet 4.0的頁面級鎖定大小爲4k,我不知道我們是否擊中了它,並且需要切換到記錄級別鎖定。
  • 我招待別人的想法,激烈,因爲他們可能是...

編輯1:
剛纔試了兩包 - >在臨界區執行()的;偶爾從DELETE FROM設置E_FAIL。

編輯2:
還試圖檢索主鍵值(代碼更新,以反映改變)

回答

1

是否有正在接收更多的描述性錯誤消息後立即關閉所述記錄?我的猜測是這是一個併發違規。您可以嘗試關閉並釋放「pADORstTable」,因爲兩個記錄集都在同一個表上運行。我也會在EOF之後關閉並釋放「pADORst」。

+0

不知道爲什麼我在6年後就對自己的問題獲得了一次讚譽..我認爲它已經佈置得很好:)無論如何,因爲你一直是唯一一個回答這一切的人,所以你獲得+1和接受的答案。歡呼,並感謝嘗試。 – 2017-11-09 13:27:48

相關問題