2012-10-17 131 views
2

我正在開發一個ipad的應用程序,我使用sqlite語句(選擇,更新,插入,刪除)。sqlite3 - iOS - 數據庫被鎖定

我打開(sqlite3_open)數據庫的開始和關閉(sqlite3_close)在每個句子的末尾。但有時我得到了「數據庫被鎖定」的消息。

我不知道我能做些什麼來解決這個問題。

感謝和抱歉,這個小小的信息。

+0

您需要提供更多的信息,比如在數據庫所在的位置,並在查詢什麼,你得到「鎖定」的消息,你怎麼查詢數據庫,你關閉你的結果集。只是不能繼續下去。我現在唯一能想到的就是數據庫文件是隻讀的,因爲它在應用程序包(資源)中。 – rckoenes

+0

可能重複[一個鏈接](http://stackoverflow.com/questions/3500635/database-is-locked-sqlite3) – Scar

回答

5

如果我沒有弄錯,sqllite的問題是您一次只能訪問一次。 如果你有多個線程,你可以在這種情況下運行。示例:

在線程t1上運行method1(訪問數據庫)。 x秒後在線程t2上運行method2(它訪問數據庫)。

如果method1在x秒內未完成,則兩種方法都將同時訪問它。 而且,正如我所說,我知道sqllite不支持這一點。

您應該嘗試標記數據庫的用法,如果您想要訪問它,但它正在使用中,請在x秒後重試。像這樣:

- (void) generalMethodThatUsesDatabses 
{ 
    if(databaseIsUsed) 
    { 
     [self performSelector:@selector(generalMethodThatUsesDatabses) withObject:nil afterDelay:5]; 
      return; 
    } 

    databaseIsUsed = TRUE; //global bool variable 


    //your code here 

    databaseIsUsed = FALSE; 

} 

希望這會有所幫助。乾杯!

+0

謝謝,我會檢查所有的代碼,並使用你的標誌;)我會評論當我得到一些結果 – javiazo

+0

我認爲這是事實,因爲你說這隻發生在「有時」。所以它可能是可靠的信息量,因此,一定的行動所需要的時間。 – George

+0

非常感謝,非常感謝! ;)由於我已經能夠發現錯誤的旗幟,一個是,我打開另一個句子中的數據庫,另一個錯誤是,我有一個「返回」裏面的句子與我關閉數據庫 – javiazo

3

您可能在使用相同的模擬器之前打開了數據庫。 要完成所有的操作到數據庫和釋放你總是 擁有所有的資源使用這兩種語句(!):

sqlite3_finalize(statement); 
sqlite3_close(database); 
+0

什麼是'(i)'在這裏? –

+0

許多初學者只包含sqlite3_close語句,假設在關閉期間自動執行finalize。事實並非如此。 – Vincent

0

來解決這方面的一個好方法是包裝成一個C++庫這一點。這樣,您可以在堆棧上創建庫包裝器。這意味着當函數超出作用域時,可以關閉析構函數中的連接。

(請注意,我使用的Objective-C的引用計數)

例如:

NSArray* ScoreBoard::getAllScores() 
{ 
     ScoreBoard::ensureExistingTable(); 

     //Stack allocated 
     SqliteWrapper sqlite("Scores.sqlite"); 

    NSArray* result = sqlite.RunQuery("SELECT * FROM Scores ORDER BY ID DESC"); 

    return result; 
    //after this, the sqlite destructor is called 
} 

這是非常高興的是,Objective-C的編譯器,您可以合併C++。它可能非常有用。

而且

void SqliteWrapper::Close() 
{ 
    sqlite3_close(db); 
} 

文森特指出,你必須完成的聲明。如果你想保持連接打開,在每個語句後使用finalize。在丟棄連接的時候關閉連接。

此方法適用於我。

-1

它用於三個方法 1.isert 2.update 3.刪除。

-(NSMutableArray *)resultSet 
-(void)insertWithTitle:(NSString *)title Body:(NSString *)body 
-(BOOL)updateAtIndex:(int)index Title:(NSString *)title Body:(NSString *)body 

NSMutableArray *result = [[[NSMutableArray alloc] initWithCapacity:0] autorelease]; 

FMResultSet *rs = [db executeQuery:[self SQL:@"SELECT * FROM %@" inTable:TABLE_NAME]]; 
while ([rs next]) { 
    Record *tr = [[Record alloc] initWithIndex:[rs intForColumn:@"id"] 
             Title:[rs stringForColumn:@"title"] 
              Body:[rs stringForColumn:@"body"]]; 
    [result addObject:tr]; 
    [tr release]; 
} 

[rs close]; 

2 ....

return result; 
[db executeUpdate:[self SQL:@"INSERT INTO %@ (title, body) VALUES (?,?)" inTable:TABLE_NAME], title, body]; 
if ([db hadError]) { 
    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 

刪除記錄:

BOOL success = YES; 
[db executeUpdate:[self SQL:@"DELETE FROM %@ WHERE id = ?" inTable:TABLE_NAME], [NSNumber numberWithInt:index]]; 
if ([db hadError]) { 
    NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 
    success = NO; 
} 
return success; 

}