美文网首页
多线程下的Sqlite(一)

多线程下的Sqlite(一)

作者: 突击手平头哥 | 来源:发表于2019-10-17 23:18 被阅读0次

    多线程下的Sqlite

    最近在多线程并发执行的情况下, 碰到了database is lock导致操作被驳回

    Sqlite多线程安全吗?

    在编译时可以设置线程模式, 可以编译为线程安全的

    Sqlite线程模式

    Sqlite的线程模式是在编译时确定的, 通过编译参数设置

    • 1 -DSQLITE_THREADSAFE = 0: 单线程模式, 所有互斥锁均被禁用多线程使用不安全
    • 2 -DSQLITE_THREADSAFE = 2: 多线程模式, 只要一个数据库连接不被多个线程同时使用就是安全的
    • 3 -DSQLITE_THREADSAFE = 1: 串行模式, 保证线程安全

    :bCoreMutexbFullMutex, 多线程模式仅开启bCoreMutex(这两种锁之后再介绍)

      可以使用int sqlite3_threadsafe(void);获取线程模式, 模式模式是序列化

    后两种模式之间可以进行设置

    如果设置为多线程模式或者串行模式, 那么可以通过sqlite3_config或者sqlite3_open_v2指定线程模式(两种模式之一)

    int sqlite3_config(int, ...);
    

    sqlite的全局设定, 请注意线程安全; 设置线程模式可选的参数SQLITE_CONFIG_SINGLETHREAD,SQLITE_CONFIG_MULTITHREAD,SQLITE_CONFIG_SERIALIZED, 注意应当在数据库初始化之前执行, 最好在程序开头执行,

    int sqlite3_open_v2(
      const char *filename,   /* Database filename (UTF-8) */
      sqlite3 **ppDb,         /* OUT: SQLite db handle */
      int flags,              /* Flags */
      const char *zVfs        /* Name of VFS module to use */
    );
    

    第三个参数, 传入SQLITE_OPEN_NOMUTEX或者SQLITE_OPEN_FULLMUTEX分别指明多线程模式和串行模式

    Sqlite的线程安全

       设置正确的前提下,多线程同时访问SQLite并不会影响数据库的完整性,而是说每个线程的数据库操作都可以正确执行; 实际上两个线程同时操作数据库的话, 有可能直接返回database is lock或者SQLITE_BUSY驳回请求
       我们的实际的要求应当是阻塞等待最后执行, 如果线程模式和使用设置不当的话就很有出现错误

    解决方案

      首先, 序列化模式不在我们考虑范围内, 那么通常办法是:

    • 1 手动加锁
    • 2 建立操作队列, 统一操作数据库

    锁的机制

    • 1 当有写操作时,其他读操作会被驳回
    • 2 当有写操作时,其他写操作会被驳回
    • 3 当开启事务时,在提交事务之前,其他写操作会被驳回
    • 4 当开启事务时,在提交事务之前,其他事务请求会被驳回
    • 5 当有读操作时,其他写操作会被驳回
    • 6 读操作之间能够并发执行

    扩展: 多进程

      多进程同时操作数据库时应当是采用了文件锁, 能够多进程读取但仅单进程写入, 同时需要注意文件系统的问题.

    相关文章

      网友评论

          本文标题:多线程下的Sqlite(一)

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