2009-06-08 63 views
9

任何人都可以提供任何输入在这个错误。我试图用Objective C插入表格。SQLite异常:SQLite忙

当我这样做时,出现错误SQLite Busy。为什么发生这种情况?

+0

你能提供一些示例代码吗?几条线了解发生了什么。 – stefanB 2009-06-08 10:21:04

回答

19

如果你调用一个函数sqlite3的错误代码SQLITE_BUSY时,得到的结果,这意味着通过drdaeman观察到该数据库已通过相同的方法或通过您的工艺中的一个线程锁定。

处理这种情况的正确方法是在循环中尝试操作,并且如果返回码仍然是SQLITE_BUSY,要等待一段时间(您决定超时值),然后在下一次重试操作循环迭代。

例如,下面的代码片段从目标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直接访问方面的使用非常简单。

+6

只需调用[sqlite3_busy_timeout](http://www.sqlite.org/c3ref/busy_timeout.html)即可完成相同的工作。 – 2012-02-02 22:11:10

7

我在顺序INSERT INTO命令中遇到了与SQLITE_BUSY类似的问题。第一行插入正常,但当应用程序尝试插入第二行时,我得到了SQLITE_BUSY状态。在谷歌周围,我知道你必须在执行它们之后调用sqlite3_finalize()语句:http://www.sqlite.org/c3ref/finalize.html。完成我的陈述解决了我的问题。

4

就我而言,我忘记了在使用它后关闭数据库。继固定雷:

sqlite3_finalize(statement); 
sqlite3_close(contactDB); 

FMDB也可以从你轻松缓解这些头疼的问题。

0

就像管理员为我运行命令提示符一样简单。另外在UNIX上,你可以在启动数据库时使用sudo