law*_*cko 6 sqlite multithreading objective-c fmdb
我有一个基于SQLite数据库的系统.每个客户端都有一个本地数据库,并且偶尔从主服务器到达一个小的delta .db文件.任务是使用增量文件合并到本地数据库,两者中的模式相同.
对于我的数据库管理,我使用fmdb包装器,可以在这里找到.在主线程中,我保持与本地数据库的连接打开.增量文件到达后台,我想在后台进行合并,以避免任何用户界面冻结,这可能导致.
至于合并本身,我发现的唯一选择是将delta数据库附加到本地数据库,然后插入/更新行,最后分离delta.这不像我预期的那样顺利.
代码说明:
码:
- (void)onDeltaGenerated:(NSNotification*)n {
NSString* deltaDBPath = [[n userInfo] objectForKey:@"deltaPath"];
@synchronized(db) {
[db executeUpdate:@"ATTACH DATABASE ? AS delta", deltaDBPath];
if ([db hadError]) {
NSLog(@" ****ERROR*** %d: %@", [db lastErrorCode], [db lastErrorMessage]);
} else {
NSLog(@"Delta attached from %@", deltaDBPath);
}
[db beginTransaction];
BOOL update1 = NO;
BOOL update2 = NO;
BOOL transaction = NO;
update1 = [db executeUpdate:@"INSERT OR REPLACE INTO equipment SELECT * FROM delta.equipment"];
if (!update1) {
NSLog(@" *** ERROR *** update 1 failed!");
NSLog(@" ****ERROR*** %d: %@", [db lastErrorCode], [db lastErrorMessage]);
}
update2 = [db executeUpdate:@"INSERT OR REPLACE INTO equipmentExt SELECT * FROM delta.equipmentExt"];
if (!update2) {
NSLog(@" *** ERROR *** update 2 failed!");
NSLog(@" ****ERROR*** %d: %@", [db lastErrorCode], [db lastErrorMessage]);
}
transaction = [db commit];
if (!transaction) {
NSLog(@" *** ERROR *** transaction failed!");
NSLog(@" ****ERROR*** %d: %@", [db lastErrorCode], [db lastErrorMessage]);
}
[db executeUpdate:@"DETACH DATABASE delta"];
if ([db hadError]) {
NSLog(@" ****ERROR*** %d: %@", [db lastErrorCode], [db lastErrorMessage]);
} else {
NSLog(@"Delta detached");
}
}
Run Code Online (Sandbox Code Playgroud)
}
在第一次调用此方法之后,在我尝试分离数据库之前,一切似乎都没有问题.当我尝试这样做时,我收到以下错误:
2012-01-11 12:08:52.106 DBApp[1415:11507] Error calling sqlite3_step (1: SQL logic error or missing database) SQLITE_ERROR
2012-01-11 12:08:52.107 DBApp[1415:11507] DB Query: DETACH delta
2012-01-11 12:08:52.107 DBApp[1415:11507] ****ERROR*** 1: database delta is locked
Run Code Online (Sandbox Code Playgroud)
我也试过相同但没有将插入插入事务,结果是相同的.另一件事是删除@synchronized子句,但也没有运气.我的猜测是,如果尝试从后台线程访问本地数据库连接失败,但那么它如何设法附加和插入?任何帮助赞赏.
编辑
我将代码移动到主线程,因此现在只从主线程访问db.问题仍然存在.
EDIT2
好吧,所以在尝试了一切之后,我放弃了这一点,然后在第一个答案出现在这里时回来了.令人惊讶的是,现在一切似乎都运行正常,所以我的代码必须正确.我怀疑这是锁定文件的不同线程的问题,因为我使用XCode,SQLiteDatabaseBrowser和我的应用程序来打开数据库.即使lsof显示该文件未被锁定,我认为它是错误的,XCode或SQLiteDatabaseBrowser都锁定了它.我认为这个问题已经解决了,从中吸取的教训不是强调这么多,而且下次还要更好地规划调试.
只需检查 \xe2\x80\x93 是否NSLog(@"Delta attached from %@", deltaDBPath);成功打印,然后您描述的错误发生了吗?
这条线Error calling sqlite3_step (1: SQL logic error or missing database) SQLITE_ERROR可能是最值得研究的地方。
经过一番谷歌搜索后,出现的一个问题是数据库文件可能无法写入。\n http://www.iphonedevsdk.com/forum/iphone-sdk-development/20142-problem-insert-fmdb.html
\n\n如果您要更新的主数据库\xe2\x80\x99 位于应用程序\xe2\x80\x99s 捆绑包中,则不允许您\xe2\x80\x99 修改它\xe2\x80\x93,您应该将其复制到Documents或首先是其他可写目录。
该错误是在您尝试分离时实际发生的,还是在您尝试执行事务时实际发生的INSERT OR REPLACE?
您是否应该在这些陈述之后再放一个if ([db hadError]) {\xe2\x80\xa6来确定?
| 归档时间: |
|
| 查看次数: |
2965 次 |
| 最近记录: |