博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sqlite并发访问
阅读量:4223 次
发布时间:2019-05-26

本文共 2151 字,大约阅读时间需要 7 分钟。

开篇闲话:

准备开始写一些技术文章,听了无数大神论述写博客的道理,却仍旧未写一篇博客。四大才子,逼格高者如岳父,拍个电影,传出无数高逼格、高冷的段子,引出一段段风潮。呵呵,扯远了,现在想写博客,最主要还是工作了一段时间以后,越来越理解为何大家都推荐写博客。引用刘未鹏在《暗时间》中一句话——书写是为了更好的思考。 感兴趣的可以看看这篇文章----《为什么你从现在开始就应该写博客?》

http://mindhacks.cn/2009/02/15/why-you-should-start-blogging-now/

闲话扯过了,进入正题。在过去一年的项目开发中,涉及使用sqlite,累积了一些经验,在这里做一个分享,也算是做一个笔记。

正题:

关于sqlite介绍、基本使用等网上的资料很多,大家可以查阅参考。

参考:

http://www.sqlite.org/(sqlite官网)

http://www.cnblogs.com/stephen-liu74/category/348367.html(一位高手整理的学习笔记)

我主要分享一下以下几方面:sqlite 的并发控制、sqlite 加密、sqlite 性能优化。这些都是我在开发中遇到的问题,且解决问题的过程中,在网上找到讲的比较清楚全面的资料相对少一些。

今天先分享一下开发sqlite中几乎必然会遇到的问题——sqlite并发访问控制。

你是否在开发使用sqlite的过程中 sqlite 抛错 database is locked 而困扰?如果是,请看下文分解。

在多线程环境下,访问sqlite是线程安全的吗?——不是,访问时需要做并发控制。

sqlite 支持 single-thread/multi-thread/serialized 三种不同的线程安全模式。可以在编译sqlite组件时进行配置,或者可以通过 sqlite3_threadsafe()/sqlite3_config() 在程序运行时进行查看并配置线程安全模式。sqlite的官网讲得很详细,参考(http://www.sqlite.org/threadsafe.html)。 通过上面的配置 sqlite 就是线程安全了吗?经过实际写 demo 测试,进行 multi-thread 或 serialized 配置以后,多线程并发读的场景下,没有问题。但是多线程并发写时依旧会抛错 database is locked。开始怀疑是因为多个线程使用了同一个数据库连接,检查代码以后发现,demo 测试的代码中每个线程都是独立的数据库连接。也就是说 sqlite 实际支持的是多读单写。         经过上面的测试以后,我们在项目中对sqlite使用了线程互斥锁进行并发控制。其实根据具体开发环境支持,更建议使用读写锁,这样并发读时效率更好。 后续在开发中又遇到了新的问题,在进行了 multi-thread 或 serialized 配置的情况下,并发写同一个数据库文件中的两张表,也会抛错 database is locked。查了资料,sqlite内部使用的是大粒度的文件锁,所有会有以上问题。当时我们因为项目需要快速上线,就做了简单的处理,直接多张表的并发控制使用同一个锁来解决,这个方案牺牲了效率,但是改动小,影响小,不涉及升级等问题。其实还可以考虑分库,把需要并发访问控制的表放到单独的数据库文件中。解决问题的方法通常有很多,根据实际的项目情况,用不同的方案。只是以上这两个方法都不算是特别好的方案。 使用了多线程互斥锁,多进程访问怎么办? 使用进程锁?效率!性能!进程锁牺牲太大,不能接受。查阅资料,发现sqlite提供两个 busy handle 函数sqlite3_busy_timeout() / sqlite3_busy_handle() 在并发访问失败时,会调用注册的 busy handle 函数,在注册的自定义的 busy handle 函数中可以进行处理(如重试n次等)。(参考:http://www.sqlite.org/c3ref/busy_handler.html) 或者直接一点,对sqlite接口做一层封装,对写数据执行失败时,识别SQLITE_BUSY错误码,进行一定条件的持续重试。(如sleep 5ms重试一次,最多重试n次) 这样可以解决问题,不过还是显得麻烦,是否还有简单的办法?还真有。直接使用

sqlite3_exec(db, “PRAGMA busy_timeout=times”, 0, 0, err); times 是设置的超时时间。这样就把重试放给 sqlite 内部去做,操作时间可设置得稍长一点(我们设置了30s)。

通过上面的方法,基本解决了多线程、多进程访问 sqlite 的问题,也不会影响 sqlite 的效率。

后续我会继续写sqlite加密和sqlite性能优化两个续篇,欢迎关注。

因个人水平有限,如有笔误、讲解不清楚、探究的不清楚的地方。还请各位海涵,并指出问题,帮助我干掉它。转载请注明出处。

http://blog.51cto.com/linzimo777/1544202

你可能感兴趣的文章
火狐下easyui1.3.*弹出window框定位不到中间解决把办法
查看>>
Hadoop启动报错NoClassDefFoundError: javax/activation/DataSource解决方案
查看>>
Python爬虫来啦,抓取数据导出到excel,简单明了,强大,直接贴代码
查看>>
Docker拉取镜像失败报错Error response from daemon: Get https://registry-1.docker.io解决办法
查看>>
IO操作的工具类总结
查看>>
对指定文件或目录进行压缩和解压缩的工具类总结
查看>>
Java中如何遍历Map对象的4种方法
查看>>
图片延时加载例子详解
查看>>
js获取url参数值的两种方式详解
查看>>
java中System.getProperty()方法详解
查看>>
MyEclipse设置默认注释的格式
查看>>
同一服务器部署多个tomcat时的端口号修改详情
查看>>
常用正则表达式集锦
查看>>
Spring定时器的时间表达式
查看>>
fastdfs简介
查看>>
主键和唯一索引的区别
查看>>
linux下使用yum安装gcc详解
查看>>
aclocal安装依赖的库
查看>>
String和常量池值的变化
查看>>
FastDFS 安装及使用详解
查看>>