任何人都可以对此错误提供任何输入.我想使用Objective C插入表中.
当我这样做时,我收到错误SQLite Busy.为什么会这样?
如果在调用sqlite3函数时得到错误代码SQLITE_BUSY,这意味着drdaeman观察到db已被同一进程或进程中的一个线程锁定.
处理这种情况的正确方法是在循环中尝试操作,如果返回代码仍然是SQLITE_BUSY,则等待一段时间(您决定超时值),然后在下一次循环迭代中重试该操作.
例如,以下代码片段取自Objective C包装器FMDB(http://code.google.com/p/flycode/source/browse/trunk/fmdb)显示如何为查询准备语句时考虑到某些操作可能会返回SQLITE_BUSY:
int numberOfRetries = 0; BOOL retry = NO; if (!pStmt) { do { retry = NO; rc = sqlite3_prepare(db, [sql UTF8String], -1, &pStmt, 0); if (SQLITE_BUSY == rc) { retry = YES; usleep(20); if (busyRetryTimeout && (numberOfRetries++ > busyRetryTimeout)) { NSLog(@"%s:%d Database busy (%@)", __FUNCTION__, __LINE__, [self databasePath]); NSLog(@"Database busy"); sqlite3_finalize(pStmt); [self setInUse:NO]; return nil; } } else if (SQLITE_OK != rc) { if (logsErrors) { NSLog(@"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]); NSLog(@"DB Query: %@", sql); if (crashOnErrors) { NSAssert2(false, @"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]); } } sqlite3_finalize(pStmt); [self setInUse:NO]; return nil; } } while (retry); }
顺便说一句,如果你需要访问sqlite,FMDB非常方便,并且在通过本机C API直接访问方面使用起来要简单得多.
如果我做对了,"忙"就意味着你无法获得锁定.似乎某个其他进程(或线程等)对数据库具有锁定.
SQLite版本3中的文件锁定和并发
我对顺序INSERT INTO命令的SQLITE_BUSY有类似的问题.第一行插入正常,但当应用程序尝试插入第二行时,我获得了SQLITE_BUSY状态.谷歌到处后,我了解到你必须在执行它们之后调用语句中的sqlite3_finalize():http://www.sqlite.org/c3ref/finalize.html .完成我的陈述解决了我的问题.