我有一个基于 SQLite 数据库的系统。每个客户端都有一个本地数据库,偶尔更新从主服务器到达,只是一个小的增量 .db 文件。任务是使用增量文件合并到本地数据库,两者的架构相同。
对于我的数据库管理,我使用可以找到的 fmdb 包装器 here .在主线程中,我保持与本地数据库的连接打开。增量文件在后台到达,我想在后台进行合并以避免这可能导致的任何用户界面卡住。
至于合并本身,我发现的唯一选择是将增量数据库附加到本地数据库,然后插入/更新行,最后分离增量。这并不像我预期的那样顺利。
代码说明:
代码:
- (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");
}
}
第一次调用此方法后,一切似乎都很好,直到我尝试分离数据库。当我尝试这样做时,出现以下错误:
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
我也尝试过同样的操作,但没有将插入插入到事务中,结果是相同的。另一件事是删除 @synchronized 子句,但也没有成功。我的猜测是,如果在尝试从后台线程访问本地数据库连接时失败,那么它是如何设法附加和插入的呢?任何帮助表示赞赏。
编辑
我将代码移至主线程,因此现在只能从主线程访问数据库。问题依然存在。
编辑2
好的,所以在尝试了所有方法之后,我暂时放弃了这个,然后在第一个答案出现在这里时又回来了。令人惊讶的是,现在似乎一切正常,所以我的代码一定是正确的。我怀疑这是不同线程锁定文件的问题,因为我使用 XCode、SQLiteDatabaseBrowser 和我的应用程序打开数据库。尽管 lsof 显示文件未被锁定,但我认为这是错误的,XCode 或 SQLiteDatabaseBrowser 正在锁定它。我认为问题已经解决了,从中吸取的教训是不要把 lsof 强推那么多,下次也可以更好地计划调试。
最佳答案
只是检查 - NSLog(@"Delta attached from %@", deltaDBPath); 是否成功打印,之后是否发生了您描述的错误?
行 Error calling sqlite3_step (1: SQL logic error or missing database) SQLITE_ERROR 可能是最值得研究的部分。
经过一些谷歌搜索后,出现的一个问题是数据库文件可能不可写。 http://www.iphonedevsdk.com/forum/iphone-sdk-development/20142-problem-insert-fmdb.html
如果您要更新的主数据库在应用程序的 bundle 中,则不允许修改它 - 您应该先将副本复制到 Documents 或其他可写目录中。
错误是在您尝试分离时实际发生的,还是在您尝试执行 INSERT OR REPLACE 事务时实际发生的?
你是否应该在这些语句之后放置另一个 if ([db hadError]) {... 来确定?
关于objective-c - 分离 SQLite 数据库时出错 - 数据库已锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8819840/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_