SQLite多线程安全2

作者: 介和 | 来源:发表于2018-12-30 19:22 被阅读0次

    1、SQLite多线程

    SQLite支持三种不同的线程模式:

    ①单线程(Single-thread)

    该模式下,所有的互斥锁被禁用;SQLite在多线程中使用是不安全的。

    当SQLite编译时加了SQLITE_THREADSAFE=0参数,或者在初始化SQLite前调用sqlite3_config(SQLITE_CONFIG_SINGLETHREAD)时启用该模式。

    ②多线程(Multi-thread)

    这种模式下,SQLite在多线程中同时使用单个数据库连接是不安全的,否则就是安全的。(不能在多个线程中并发使用同一个数据库连接)。

    ③串行(Serialized)

    在串行模式下,SQLite在多线程中使用是安全的。

    线程模式可以在编译时(通过源码编译sqlite库时)、启动时(使用sqlite的应用程序初始化时)或者运行时(创建数据库连接时)来指定。一般而言,运行时指定的模式将覆盖启动时的指定模式,启动时指定的模式将覆盖编译时指定的模式。但是,单线程模式一旦被指定,将无法被覆盖。

    默认的线程模式是串行模式。

    编译时选择线程模式

    可以通过定义SQLITE_THREADSAFE宏来指定线程模式:

    SQLITE_THREADSAFE=1指定使用串行模式;

    SQLITE_THREADSAFE=0使用单线程模式;

    SQLITE_THREADSAFE=2使用多线程模式。

    如果没有指定,默认为串行模式。

    官方链接:Using SQLite In Multi-Threaded Applications

    2、iOS平台的SQLite

    在iOS平台上,默认使用的是第2种线程模式编译的(Multi-thread),也就是只有一个线程能够打开数据库操作,其他线程要操作数据库必须等数据库关闭后才能打开操作。多线程时:每个线程独立打开数据库,操作数据库,操作完后关闭数据库。打开和关闭都比较费时间,而且要手动控制打开关闭锁,在每个线程操作不频繁时可用该方法。

    如果多个线程频繁操作数据库,使用以上方法很容易造成系统崩溃,解决方案:

    ①开启第3种串行模式,使用一个类(单例方式)操作数据库。

    ②使用串行队列操作数据库。

    2.1 开启第3种串行模式,使用一个类(单例方式)操作数据库。

    - (BOOL)open {

        if (_db) {

            return YES;

        }

        int err = sqlite3_config(SQLITE_CONFIG_SERIALIZED);

        if(err != SQLITE_OK) {

            NSLog(@"error configing!: %d", err);

            return NO;

        }

        err = sqlite3_open([self sqlitePath], (sqlite3**)&_db );

        if(err != SQLITE_OK) {

            NSLog(@"error opening!: %d", err);

            return NO;

        }

        if (_maxBusyRetryTimeInterval > 0.0) {

            // set the handler

            [self setMaxBusyRetryTimeInterval:_maxBusyRetryTimeInterval];

        }

        return YES;

    }

    2.2 使用串行操作队列操作数据库。

    1、创建操作列队

    - (id)initWithPath:(NSString *)path

    {

        self = [super init];

        _path = path;

        _databaseQueue = [[NSOperationQueue alloc] init];

        [_databaseQueue setMaxConcurrentOperationCount:1];

        return self;

    }

    - (void)queueDatabaseOperation:(StorageOperation *)request

    {

        [_databaseQueue addOperation:request];

    }

     原文:https://blog.csdn.net/xuhen/article/details/78967846

    相关文章

      网友评论

        本文标题:SQLite多线程安全2

        本文链接:https://www.haomeiwen.com/subject/lgtblqtx.html