我有一個iPhone應用程序正在使用sqlite 3.6(不與FMDB)來存儲和加載數據。當應用程序加載並通過整個應用程序使用相同的數據庫連接時,我加載數據庫。sqlite和線程與iPhone SDK
在後臺線程中,應用程序從Web服務器下載一些數據並寫入數據庫。同時主線程也可能需要寫入相同的數據庫。這有時會導致EXC_BAD_ACCESS,因爲兩個線程都試圖訪問數據庫。
什麼是能夠從不同線程使用數據庫的最好和最簡單的方法?
這是顯示問題的例子:
sqlite3 *database;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"database.db"];
if (sqlite3_open([path UTF8String], &database) != SQLITE_OK) {
sqlite3_close(database);
return YES;
}
[NSThread detachNewThreadSelector:@selector(test) toTarget:self withObject:nil];
[self test];
return YES;
}
-(void)test {
for (int i = 0; i < 2000; i++) {
NSLog(@"%i",i);
sqlite3_exec([self getDb],"UPDATE mytable SET test=''", 0, 0, 0);
}
}
編輯:
後willcodejavaforfood的答案在下面,我試圖改變我的代碼使用單獨的數據庫對象(連接)的每個單獨的線程並且還添加了sqlite3_busy_timeout(),這樣sqlite將在數據庫繁忙時重試寫入。現在我不再獲得EXC_BAD_ACCESS,但我注意到並非所有數據都被插入。所以這也不是一個穩定的解決方案。這似乎是真的很難得的SQLite與穿線工作..
我與獨立連接新的解決方案:
-(void)test {
sqlite3 *db = [self getNewDb];
for (int i = 0; i < 2000; i++) {
NSLog(@"%i",i);
sqlite3_exec(db,"UPDATE mytable SET test=''", 0, 0, 0);
}
}
- (sqlite3 *)getNewDb {
sqlite3 *newDb = nil;
if (sqlite3_open([[self getDbPath] UTF8String], &newDb) == SQLITE_OK) {
sqlite3_busy_timeout(newDb, 1000);
} else {
sqlite3_close(newDb);
}
return newDb;
}
感謝您的回答!但是,在所有線程和SQLITE_OPEN_FULLMUTEX(SQLite,序列化模式)之間使用一個連接有什麼問題?就像我以前問過的那樣,有什麼缺點? – mrrmatinsi 2010-12-02 18:45:48
您是否閱讀過指南? – willcodejavaforfood 2010-12-02 18:48:44