我有一個視圖,在後臺線程插入數據來自服務器的sqlite數據庫。現在當用戶點擊並導航到另一個視圖時,我必須從這個數據庫讀取內容,但是我無法獲取內容,因爲數據庫已經在最後一個視圖的後臺線程中打開,並且出現錯誤「數據庫已鎖定」。同步sqlite數據庫的目標-C
注意:這兩個操作都在不同的表格中,即我正在寫入不同的表格並從其他表格讀取。
sqlite是否支持多線程,如果是的話我該如何從數據庫中刪除鎖?
我有一個視圖,在後臺線程插入數據來自服務器的sqlite數據庫。現在當用戶點擊並導航到另一個視圖時,我必須從這個數據庫讀取內容,但是我無法獲取內容,因爲數據庫已經在最後一個視圖的後臺線程中打開,並且出現錯誤「數據庫已鎖定」。同步sqlite數據庫的目標-C
注意:這兩個操作都在不同的表格中,即我正在寫入不同的表格並從其他表格讀取。
sqlite是否支持多線程,如果是的話我該如何從數據庫中刪除鎖?
SQLite支持多線程。你可以在線程之間共享你的連接句柄/對象,他們會很好地同步他們的訪問。
編輯:將sqlite3
對象(sqlite3_open()
作爲第二個參數返回的對象)傳遞給線程,而不是在線程中重新打開數據庫。事情是這樣的:
sqlite3 *MyDatabase; //Initialized somewhere
NSArray *DataForThread = [NSArray arrayWithObjects:
request,
[NSValue valueWithPointer: MyDatabase],
nil];
[self performSelectorInBackground:@selector(processResponseInBackground:) withObject:DataForThread];
的線程內,恢復SQLite3的對象是這樣的:
sqlite3 *MyDatabase = [[ThreadData objectAtIndex:1] pointerValue];
SQLite的不支持多線程,但它不支持從多個線程數據庫同時訪問。
如果您正在從Objective-C中的多個線程訪問SQLite,您應該使用某種鎖定機制來協調對數據庫句柄的訪問。一個選項是@synchronized關鍵字。
至於在同一時間從數據庫中讀取插入正在發生在另一個線程上,您需要變得有創意。
一種選擇是將兩個表放入兩個不同的數據庫並創建兩個不同的連接。
在多線程環境中使用SQLite的自然延伸閱讀:
SQLite支持在「寫了這麼快,以避免併發問題意識的多線程」。現實情況是,在只讀查詢的情況下不應該存在鎖定問題,但是如果你想寫太多......你可能會遇到SQLITE_BUSY錯誤。 你能避免它在幾個方面:
要麼做所有查詢到同一個線程(但如果你能做到這一點?如上所述,將數據庫表分成兩個或多個文件(將具有較少併發訪問或具有隻讀訪問的表分組在一起),併爲每個文件創建一個不同的數據庫連接
或者,如上所述,對每個執行查詢的方法(或代碼塊)使用線程同步方法(確保在您開始事務時使用「BEGIN IMMEDIATE TRANSACTION」將數據庫鎖定)
或者,通過c api提供的2個回調來處理sqlite:busy錯誤,「sqlite_busy_handler」和「sqlite_bus y_timeout」
或如果需要的話,接收鎖定錯誤等待1-2秒,然後重試後(更好接近點以上我覺得)
我寧願減少併發分裂分貝,然後同步線程訪問查詢代碼。這只是你的選擇...
@Seve如果你提供了一些代碼將是很好的。謝謝 –
你先。你如何打開數據庫並啓動後臺線程? –
在數據來自服務器的第一個視圖中,使用'[self performSelectorInBackground:@selector(processResponseInBackground :) withObject:request]'在後臺插入數據;''當我從這個視圖導航它仍然使用數據庫和數據庫被鎖定爲另一個視圖 –