iOS上Sqlite多線程問題


1.單線程:禁用所有的mutex鎖,並發使用時會出錯。當SQLite編譯時加了SQLITE_THREADSAFE=0參數,或者在初始化SQLite前調用sqlite3_config(SQLITE_CONFIG_SINGLETHREAD)時啟用。
2.多線程:只要一個數據庫連接不被多個線程同時使用就是安全的。源碼中是啟用bCoreMutex,禁用bFullMutex。實際上就是禁用數據庫連接和prepared statement(准備好的語句)上的鎖,因此不能在多個線程中並發使用同一個數據庫連接或prepared statement。當SQLite編譯時加了SQLITE_THREADSAFE
=2參數時默認啟用。若SQLITE_THREADSAFE不為0,可以在初始化SQLite前,調用sqlite3_config(SQLITE_CONFIG_MULTITHREAD)啟用;或者在創建數據庫連接時,設置SQLITE_OPEN_NOMUTEX flag。
3.串行:啟用所有的鎖,包括bCoreMutex和bFullMutex。因為數據庫連接和prepared statement都已加鎖,所以多線程使用這些對象時沒法並發,也就變成串行了。當SQLite編譯時加了SQLITE_THREADSAFE
=1參數時默認啟用。若SQLITE_THREADSAFE不為0,可以在初始化SQLite前,調用sqlite3_config(SQLITE_CONFIG_SERIALIZED)啟用;或者在創建數據庫連接時,設置SQLITE_OPEN_FULLMUTEX flag。

  在iOS上,默認使用的是第2種方式編譯的,也就是只有一個線程能夠打開數據庫操作,其他線程要操作數據庫必須等數據庫關閉后才能打開操作。多線程時:每個線程獨立打開數據庫,操作數據庫,操作完后關閉數據庫。打開和關閉都比較費時間,而且要手動控制打開關閉鎖,在每個線程操作不頻率時可用該方法。

  如果多個線程頻繁操作數據庫,使用以上方法很容易造成系統崩潰,解決方案:開啟第3種串行模式,使用一個類(單例方式)操作數據庫。

-(BOOL)open
{
    sqlite3_shutdown();
    NSLog(@"sqlite3 lib version: %s", sqlite3_libversion());
    int err=sqlite3_config(SQLITE_CONFIG_SERIALIZED);
    if (err == SQLITE_OK) {
        NSLog(@"Can now use sqlite on multiple threads, using the same connection");
    } else {
        NSLog(@"setting sqlite thread safe mode to serialized failed!!! return code: %d", err);
    }
    err = sqlite3_open([VersionDBPath UTF8String], &hSqlite3DB);
    if(err != SQLITE_OK) {
        NSLog(@"datebase open error: %d", err);
        return NO;
    }
    return YES;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM