2011-11-30 4 views
3

Sqlite3 DB에서 검색을 수행하는 쿼리가 있습니다. 독자를 사용하여 읽는 것 외에는 아무것도하지 않습니다. 일치하는 각 일치에 대해 결과보기를 업데이트하는 UI에 대한 콜백을 호출합니다.iPhone의 Sqlite3 데이터베이스가 잠긴 경우 - 피하는 법?

이 검색이 실행되는 동안 UI에서 새 스레드에서 다른 작업을 수행하는 버튼을 누르십시오. 결국 검색 컨트롤러의보기를 제거하고 새 컨트롤러를 표시합니다.

그러나 트리거 된 동작은 데이터베이스에 쓰기를 원합니다. 그리고 거기에 그냥 걸려 결국 DB를 잠겨있는 예외가 표시됩니다.

흥미로운 점은 검색 리더가 계속되지 않는다는 것입니다. 교착 상태입니다.

다중 스레드 사용을 지원하기 위해 특별한 방법으로 데이터베이스를 열어야합니까? 연결에 대한 생성자는 무엇입니까?

답변

1

MonoTouch 5.1+는 SQLite에서 사용할 스레딩 모델을 선택할 수 있도록 API을 제공합니다.

SqliteConnection.SetConfig (SQLiteConfig.MultiThread); 

이 주소는 SQLite 라이브러리의 options에 매핑됩니다.

UPDATE : 당신은 ((의 지침에 따라) 또는 패치를 복사 - 붙여 넣기 버그 리포트 #652에 부착 된 바이너리를 사용할 수 있습니다 (예를 들어 4.2 및 5.0.x는 사이) MonoTouch의 이전 버전을 사용하는 경우 p/invoke 및 enum)을 사용합니다.

+0

오류, SQLiteConnection에 대한 SetConfig 메서드가없고 더 정확하게 SqliteConnection (소문자 체크 아웃) 만 있습니다. Mono.Data.Sqlite를 참조하고 있습니다. MT 5.0.2에 있습니다. – Krumelur

+0

죄송합니다. 소스 파일 이름을 사용했지만,이 경우 입력 유형 이름과 일치하지 않습니다. Mono 소스 코드). 또한 5.0의 일부가 아닙니다 (4.2와 동일한 모노 코드/분기를 사용합니다). 고객이 테스트했지만 http://bugzilla.xamarin.com/show_bug.cgi?id=652 (5.0.x에서 제공하는 버전이 아님)에서 첨부 파일을 사용하여 혼란스러워졌습니다. – poupou

+0

MT 5.1이 iOS SDK 5.1과 함께 제공 될 것입니다. – Krumelur

1

설명을 올바르게 해석 할 수는 없지만 설명하는 방식에 따라 "리더"가 데이터베이스를 단계별로 실행하고 결과를 찾을 때마다 콜백 함수에 대한 콜백? 이 올바른지?

그런 경우 반복해서 DB를 잠그면 검색 속도가 느려질 수 있습니다.

올바른 방법은 단일 쿼리에서 결과 집합으로 모든 일치 항목을 추출하는 것입니다. 쿼리가 완료되면 잠금이 해제되고 일치하는 행만 포함 된 SQL에서 결과 집합을 갖게됩니다.

당신은 SQLite는이 유형의 쿼리를 사용하여 다음과 같은 결과 집합을 만들 수 있습니다 "이 SELECT * FROM tablename WHERE COLUMNX LIKE '%의 검색 문장의 %'"

(또는 이와 유사한, 당신의 검색 기준에 따라)

그러면 데이터베이스에서 모든 일치 항목과 함께 결과 세트가 작성된 다음 데이터베이스 잠금이 해제됩니다. 그런 다음 결과를 단계별로 실행하여 개체를 만들고 UI 뷰에 연결된 NSArray를 삽입 할 수 있습니다. 이 방법을 수행

NSArray retval = [NSMutableArray array]; 

//Create a query 
NSString *query = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ LIKE %@", 
tableName, columnName, searchString]; 

sqlite3_stmt *statement; 

//Database locks here 
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil) 
== SQLITE_OK) { 
    //Database should unlock here, the query is finished 
    while (sqlite3_step(statement) == SQLITE_ROW) { 
     char *nameChars = (char *) sqlite3_column_text(statement, 0); 
     NSString *name = [NSString stringWithUTF8String:nameChars]; 
     SomeClass *info = [[SomeClass alloc] initWithName:name]; 

     /* Extract other columns and put in your object */ 

     [retval addObject:info]; 
     [info release]; 
    } 
sqlite3_finalize(statement); 
} else { 
    NSLog(@"SQL-statement failed"); 
} 

이 필요한 때 DB에 기록 할 수있는 문제가 안된다. 검색 조건이 변경되거나 DB의 내용이 업데이트 된 경우와 같이 절대적으로 필요한 경우에만 DB에 대한 새 쿼리를 수행하십시오.

DB가 변경되지 않았거나 변경되지 않은 검색 기준을 사용하여 반복 된 쿼리를 실행하지 마십시오.

+0

문제는 다음과 같습니다. 쿼리가 매우 오래 걸립니다. 따라서 쿼리가 끝날 때까지 기다리지 않으려 고합니다. 발견되는대로 결과를 보여주고 싶습니다. 그러나 자물쇠 문제에 대한 설명에 감사드립니다! – Krumelur

+0

오, 그리고 유일한 옵션으로 qt Sqllite Monotouch에서 ExecuteReader() 명령을 것입니다. Prepare() 메소드가 있지만 Step이나 이와 비슷한 것이 없습니다. – Krumelur

+0

ios SDK에 포함 된 sqlite3-lib를 사용하면 더 이상 충분하지 않습니다. –

관련 문제