2013-05-22 3 views
2

iOS 응용 프로그램에서 SQLite로 만든 색인을 삭제하는 데 문제가 있습니다. 나는 fmdb을 사용하고 있습니다.iOS에서 fmbd로 SQLite 색인을 삭제하는 데 SQLITE_LOCKED가 발생하지 않습니다.

인덱스를 삭제하려고 시도하면 sqlite3_step은 항상 SQLITE_LOCKED을 반환합니다. 결과적으로 fmdb는 계속해서 drop 문 (매번 sqlite3_stepSQLITE_LOCKED을 반환 함)을 재 시도하려고하는 무한 루프에 걸리며 명령문은 성공하지 못합니다.

내가 아는 한, drop 문이 작동하기 바로 전에 데이터베이스와 문을 만지는 다른 프로세스는 문제없이 존재합니다. 내가 뭘 놓치고 있니?

[db open]; 
/* ... */ 
[db executeUpdate:@"DROP INDEX IF EXISTS bookmark_hash_idx;"]; 
[db close]; 

db 내 문서 디렉토리에 SQLite는 데이터베이스에 대한 포인터입니다 :

여기에 거의 실패 년대 코드를 그대로 복사합니다. 그 유용 경우

여기, fmdb에서 관련 코드입니다 :

do { 
    rc  = sqlite3_step(pStmt); 
    retry = NO; 

    if (SQLITE_BUSY == rc || SQLITE_LOCKED == rc) { 
     // this will happen if the db is locked, like if we are doing an update or insert. 
     // in that case, retry the step... and maybe wait just 10 milliseconds. 
     retry = YES; 
     if (SQLITE_LOCKED == rc) { 
      rc = sqlite3_reset(pStmt); 
      if (rc != SQLITE_LOCKED) { 
       NSLog(@"Unexpected result from sqlite3_reset (%d) eu", rc); 
      } 
     } 
     /* ... */ 
    } 
    /* ... */ 
} while (retry); 
+0

앱 번들에 파일을 쓰려고하지 않습니다. 그렇습니까? –

+0

'sqlite3_step' 대신'sqlite3_exec'을 사용하여 스키마를 업데이트 해보십시오. – rmaddy

+0

Nope. 내 문서 디렉토리에 있어요. –

답변

4

당신은 아마 통과하기 위해 DROP 색인을 차단 개방 결과 집합을 가지고있다. SQLite는 docs에서 :

은 "DROP 표"예외

전화가 sqlite3_step하는() SQLITE_LOCKED 반환, 그것은 거의 항상 sqlite3_unlock_notify를 호출하는 것이 적절하다(). 그러나 한 가지 예외가 있습니다. "DROP TABLE"또는 "DROP INDEX"문을 실행하면 SQLite는 동일한 연결에 속한 현재 실행중인 SELECT 문이 있는지 확인합니다. 존재하는 경우, SQLITE_LOCKED가 리턴됩니다. 이 경우 "블로킹 연결"이 없으므로 sqlite3_unlock_notify()를 호출하면 unlock-notify 콜백이 즉시 호출됩니다. 그런 다음 응용 프로그램이 "DROP TABLE"또는 "DROP INDEX"쿼리를 다시 시도하면 무한 루프가 결과 일 수 있습니다.

당신은 열려있는 모든 결과 집합을 확인하기 위해 FMDatabase 객체에 closeOpenResultSets를 호출해야

는 인덱스를 삭제하기 전에 닫힙니다.

+0

열린 결과 집합이 잠금을 일으키는 지 확인할 수있는 방법이 있습니까? –

+1

SQLite_LOCKED를보고있는 FMDatabase 안에 breakpoint를 설정하고,'po self -> _ openResultSets'로 로깅하십시오. – Anurag

+0

@ Dan - 단지 궁금해서 열린 결과가 문제를 설정 했습니까? – Anurag