2009-06-08 56 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