SQLite数据库中多线程使用问题

SQLite数据库中多线程使用问题,第1张

概述由于项目是接手之前的烂尾项目,经常被吐槽说界面卡半天,后来发现项目里的网络请求,数据库 *** 作都是在主线程。将一些长时间的 *** 作换到多线程或者异步之后后,用户交互是变的顺畅多了,可是经常出现莫名其妙的闪退,还有数据插入错表的情况(用户表数据插入到消息表中)。 因为项目比较早,用的三方库都比较旧,所以数据库用的是SQLitePersistentObject,本以为是数据库比较老旧问题,因为数据 *** 作遍布数据

由于项目是接手之前的烂尾项目,经常被吐槽说界面卡半天,后来发现项目里的网络请求,数据库 *** 作都是在主线程。将一些长时间的 *** 作换到多线程或者异步之后后,用户交互是变的顺畅多了,可是经常出现莫名其妙的闪退,还有数据插入错表的情况(用户表数据插入到消息表中)。

因为项目比较早,用的三方库都比较旧,所以数据库用的是sqlitePersistentObject,本以为是数据库比较老旧问题,因为数据 *** 作遍布数据库各处,也只能先帮办法解决问题,以后在考虑重构、优化了。网上也没有报出说这个三方库有什么问题。后来看到一篇博客中详细讲解了下sqlite的线程安全机制。

原文地址:http://www.jb51.cc/article/p-dufjxyed-bct.html

虽然有点长,写的不优美,但是仔细看完,收货还是颇丰。


重要内容摘出来


sqlite支持3种线程模式:

单线程:禁用所有的mutex锁,并发使用时会出错。当sqlite编译时加了sqlITE_THREADSAFE=0参数,或者在初始化sqlite前调用sqlite3_config(sqlITE_CONfig_SINGLETHREAD)时启用。
多线程:只要一个数据库连接不被多个线程同时使用就是安全的。源码中是启用bCoreMutex,禁用bFullMutex。实际上就是禁用数据库连接和prepared statement(准备好的语句)上的锁,因此不能在多个线程中并发使用同一个数据库连接或prepared statement。当sqlite编译时加了sqlITE_THREADSAFE=2参数时默认启用。若sqlITE_THREADSAFE不为0,可以在初始化sqlite前,调用sqlite3_config(sqlITE_CONfig_MulTITHREAD)启用;或者在创建数据库连接时,设置sqlITE_OPEN_NOMUTEX flag。
串行:启用所有的锁,包括bCoreMutex和bFullMutex。因为数据库连接和prepared statement都已加锁,所以多线程使用这些对象时没法并发,也就变成串行了。当sqlite编译时加了sqlITE_THREADSAFE=1参数时默认启用。若sqlITE_THREADSAFE不为0,可以在初始化sqlite前,调用sqlite3_config(sqlITE_CONfig_SERIAliZED)启用;或者在创建数据库连接时,设置sqlITE_OPEN_FulLMUTEX flag。

而这里所说的初始化是指调用sqlite3_initialize()函数,这个函数在调用sqlite3_open()时会自动调用,且只有第一次调用是有效的。

另一个要说明的是prepared statement,它是由数据库连接(的pager)来管理的,使用它也可看成使用这个数据库连接。

因此在多线程模式下,并发对同一个数据库连接调用sqlite3_prepare_v2()来创建prepared statement,或者对同一个数据库连接的任何prepared statement并发调用sqlite3_bind_*()和sqlite3_step()等函数都会出错(在iOS上,该线程会出现EXC_BAD_ACCESS而中止)。这种错误无关读写,就是只读也会出错。

文档中给出的安全使用规则是:没有事务正在等待执行,所有prepared statement都被finalized顺带一提,调用sqlite3_threadsafe()可以获得编译期的sqlITE_THREADSAFE参数。标准发行版是1,也就是串行模式;而iOS上是2,也就是多线程模式;Python的sqlite3模块也默认使用串行模式,可以用sqlite3.threadsafety来配置。但是默认情况下,一个线程只能使用当前线程打开的数据库连接,除非在连接时设置了check_same_thread=False参数。

总结,数据库要多线程 *** 作,需要每个线程与数据库建立连接,还需要设置锁、线程等参数。多条线程公用同一个数据库连接就会出错。

总结

以上是内存溢出为你收集整理的SQLite数据库中多线程使用问题全部内容,希望文章能够帮你解决SQLite数据库中多线程使用问题所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1170087.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存