最近面試被問到FMDB的多線程處理問題,由於以前項目中是移植別人的代碼,沒有踩過這裏的坑。html
多線程同時訪問數據庫時,報數據庫鎖定的問題,錯誤信息是:面試
Unknown error finalizing or resetting statement (5: database is locked)sql
文件數據庫sqlite,同一時刻容許多個進程/線程讀,但同一時刻只容許一個線程寫。在操行寫操做時,數據庫文件被瑣定,此時任何其餘讀/寫操做都被阻塞,若是阻塞超過5秒鐘(默認是5秒,能太重新編譯sqlite能夠修改超時時間),就報"database is locked"錯誤。因此,在操做sqlite時,應該即時關閉鏈接;打開鏈接後,儘可能減小很是費時的操做。數據庫
FMDatabase **不能多線程使用一個實例多線程訪問數據庫,不能使用同一個**FMDatabase 的實例。不然會發生異常。若是線程使用單獨的FMDatabase 實例是容許的,可是一樣有可能發生database is locked的問題。這是因爲多線程對sqlite的競爭引發的.多線程
FMDatabaseQueue 解決這個問題的思路是:建立一個隊列(串行線程隊列),而後將放入的隊列的block順序執行,這樣避免了多線程同時訪問數據庫線程
解決方案 共享同一個FMDatabaseQueue**實例**orm
注意:sqlite
本來使用FMDatabase類,須要手工調用db的open和close方法,可是用FMDatabaseQueue,不須要調用open,由於查看代碼發現,Queue已經open了。htm
因此,使用Queue,是不須要本身打開和關閉db的。可是若是使用了FMResultSet,rs卻是須要關閉,不然會報warning:
if ([db hasOpenResultSets]) {
NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]");隊列
引伸閱讀
Reference: