問題一: "is currently in use" 出現的場景是這樣的,多線程操作數據庫,每個線程都使用了FMDatabase實例(注意沒有使用FMDatabaseQueue)。
問題二:“database is locked"出現的場景是這樣的,多線程操作數據庫,每個線程各自創建了FMDatabaseQueue實例操作數據庫,或者一個線程創建FMDatabaseQueue實例來操作,而另外的線程創建了FMDatabase實例來操作。
解決:FMDB多線程操作數據庫,必須使用FMDatabaseQueue,必須只創建一個實例,也就是多個線程操作數據庫的是同一個FMDatabaseQueue實例。
原因:因為首先FMDatabase是不具備線程安全的,如果兩個線程中同時操作數據庫,就會"is currently in use" ;FMDatabasequeue其實是一個調度隊列(G-C-D),數據庫的操作必須是順序執行,不能兩個數據庫的操作同時執行,如果是兩個線程各自創建了FMDatabaseQueue的實例,線程同時執行時,就會出現相同的數據庫操作同時觸發,導致”database is locked“,所以必須是一個FMDatabaseQueue實例下,多個線程下同時操作,其實是在排在同一個隊列中逐一操作的,沒有同時操作。
PS:以下就是我的解決方式
1 #PRagma mark - 配置數據庫單聊 2 +(FMDatabaseQueue *)getSharedDatabaseQueue 3 { 4 static FMDatabaseQueue *my_FMDatabaseQueue=nil; 5 6 if (!my_FMDatabaseQueue) { 7 NSString *path = [kDocuments stringByAppendingPathComponent:@"db_CMBCC.sqlite"]; 8 my_FMDatabaseQueue = [FMDatabaseQueue databaseQueueWithPath:path]; 9 }10 return my_FMDatabaseQueue;11 }
- (void)SaveSingleChatMessage:(MessageEntityModel *)messageEntity{ FMDatabaseQueue *queue = [StoreManagerHelper getSharedDatabaseQueue]; [queue inDatabase:^(FMDatabase *db) { //打開數據庫 if ([db open]) { //數據庫建表,插入語句 } else { NSLog(@"打開數據庫失??!"); } }];}
新聞熱點
疑難解答