2011-12-27 2 views
-1

문제 : 나는 각각 제트 4.0 MDB에 열린 자신의 연결이 두 스레드 각각에 E_FAIL의 조합 및 데이터베이스 손상을보고 있어요
.ADO 삽입하고 2 개 개의 다른 연결에서 실행 삭제됩니다 오류

시나리오 :

스레드 (1)는 메인 스레드입니다 :
내가 응용 프로그램이 있습니다. 그것은 "Microsoft.Jet.OLEDB.4.0"공급자를 사용하는 Jet 4.0 mdb에 대해 ADO 연결을 엽니 다. 그것은

hr = pADOConn->Execute("INSERT INTO ...", NULL, adCmdText|adExecuteNoRecords, NULL); 
// occasionally returns E_FAIL 

스레드 2 경유하여 MDB에있는 두 테이블 중 하나에 데이터를 삽입 할 책임이 또한 동일한 연결 문자열 오픈 ADO 연결을 가지고 스레드 1의 자식입니다. 각 테이블에 이미있는 레코드를 반복하여 서버에 각 행을 "펌핑"한 다음 테이블에서 행을 삭제합니다. 이것은을 통해 수행됩니다 (단 관련 부분에 약식) :

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가 여러 연결에서 들어오는 요청을 처리 할 수 ​​있어야하기 때문에 과감한 것처럼 보입니다.
  • 나는 Jet4.0의 페이지 레벨 잠금 크기 인 4k에 익숙해 있으며, 우리가 그것을 치고 있는지, 그리고 레코드 잠금 수준으로 전환해야하는지 궁금합니다.
    그냥 모두 포장 시도 -> 중요한 섹션에()의 실행;
  • 나는

편집 1 ... 그들이 할 수 있으므로 격렬한, 다른 사람의 생각을 즐겁게합니다 DELETE FROM에서 때때로 E_FAIL을 설정합니다.

편집 2 :
은 또한 (변경 사항을 반영하기 위해 업데이트 된 코드) 기본 키 값

답변

1

을 받고있는 더 설명이 포함 된 오류 메시지가 거기를 검색 한 후 즉시 레코드 집합을 닫는 시도? 내 생각 엔 동시성 위반입니다. 두 테이블 세트가 같은 테이블에서 작동하기 때문에 "pADORstTable"을 닫고 해제 할 수 있습니다. 나는 또한 EOF 후에 "pADORst"를 닫고 발표 할 것입니다.

+0

6 년 후에 내 질문에 downvote를 얻은 이유는 확실하지 않습니다. 나는 꽤 잘 짜여진 줄 알았습니다. :) 어쨌든이 시간에 당신이 대답 할 수있는 유일한 사람 이었기 때문에, +1과 대답을받습니다. 환호와 노력에 감사드립니다. –

관련 문제