前些时候,同事在站点服务端使用SQlite存储一些临时数据,但是在多人并发的时候Sqlite会抛出异常:The database file is locked , database is locked,而且这个是在客户生产环境下提示出来的,开发环境很难重现,同事实在没辙,竟然想发动所有研发同事通过操作软件重现问题,我只能呵呵了。既然是Sqlite的原因,直接写个小程序测试下sqlite不就行了,而且就算重现了,难不成要改Sqlite源码...

  Sqlite的特点:

  1. 简单(simple):SQLite是一个非常轻量级自包含(lightweight and self-contained)的DBMS:一个头文件,一个动态库文件,你就拥有了关系数据库的所有功能了。简单,是SQLite最明显的哲学。它提供的API少而简单。只需要一个DLL文件,你的程序马上就拥有了一个功能强大的数据库引擎,这是一件很美妙的事。
  2. 小巧(small):我用VS 2005在Windows下编译的3.6.11,Release版为368K,用时不到20秒——而编译MySQL时,要花上几分钟。而当我插入10000条int数据时,内存开销660K,磁盘开销92K。
  3. 事务(transaction):事务是现代商业数据处理系统最基本的要求,而Access,不论是在可执行文件大小(看了一下Access2003的可执行文件大小为6.32M,两者不是一个量级),还是事务特性,都是不能和SQLite 相比的。
  4. 并发性(Concurrency):由于SQLite通过OS的文件锁来实现库级锁,粒度很大,但是,它通过一些复杂特殊的处理(具体可以参见分析系列),尽量的提升了读写的并发度。
  5. SQL92:SQLite支持绝大部分的标准SQL语句,你只需要几百K的空间,就可以换来需要上百兆的通用DBMS几乎所有操作了。
  6. 方便(Convenience):如果你的程序要使用SQLite,只需要将拷贝你的程序目录即可。
  7. 开源(Opensource):这是它最强大的地方。开源,意味着你可以品读它的源码,你可以随时修改它,加入你自己的特性,而这一切完全免费的。开源,是一种精神

  SQLite只支持库级锁,库级锁意味着什么?——意味着同时只能允许一个写操作,也就是说,即事务T1在A表插入一条数据,事务T2在B表中插入一条数据,这两个操作不能同时进行,即使你的机器有100个CPU,也无法同时进行,而只能顺序进行。表级都不能并行,更别说元组级了——这就是库级锁。但是,SQLite尽量延迟申请X锁,直到数据块真正写盘时才申请X锁,这是非常巧妙而有效的。

  上面的介绍可以看出Sqlite其实是一个客户端嵌入数据库,在高并发的服务器上是无法适用的,同事百度后,发现连接串中加入 "Journal Mode=WAL;"可以缓解并发压力,可是客户生产环境仍然出现“database is locked”错误。

我们可以编写一个测试案例,代码很简单的,并发的执行多条update语句,使用不同的机子,一般选择一个性能好点的机子(我测试的时候使用的是G4)和一个性能差点的机子(G2)

测试发现,在G2机器上,跑了不到半分钟,大概执行了500条Update语句,Sqlite就报错,提示“ database is locked”,但是在G4机器上很难发现,这也就解释了开发机上难重现而在客户服务器上报错的现象。

这里要仔细看一下上面标注红色的内容,因为我刚开始没有使用任何同步机制来进行操作的,使用的G4手机测试的,结果一运行就报错,所以上网查询原因,结果说是对一个表进行操作的时候,需要进行加锁,所以我就在对同一个表进行CRUD操作的时候,使用了同一个锁,运行没有错,但是过了几天之后,测试那边的人给一个bug表,尽然出现了上面的问题,而且是G2机器,所以我就用这个机器进行测试,果然发现会出现上述的问题,这时候就很纠结了,网上各种搜索,无果,结果看到一篇文章说到了重点,说sqlite是库级锁,那么我就将上面的表级锁改成了库级锁(很简单,不同的表都是用同一个锁),在测试发现没有上述问题了。。

解决SQLite中的 database is locked的更多相关文章

  1. SQLITE报错database is locked的解决办法

    用firedac连接SQLITE数据库,空间tdbedit绑定字段name,如下语句修改其值时报错. procedure TForm1.Button3Click(Sender: TObject);be ...

  2. 解决SQLite database is locked

    前些时候,同事在站点服务端使用SQlite存储一些临时数据,但是在多人并发的时候Sqlite会抛出异常:The database file is locked , database is locked ...

  3. sqlite:多线程操作数据库“database is locked”解决方法(二)

    上一篇博客<sqlite:多线程操作数据库“database is locked”解决方法>通过注册延时函数的方法来处理数据库被锁的问题.此方法固然能解决问题,但是在多个线程向数据库写入大 ...

  4. sqlite遇到database is locked问题的完美解决

    这两天在项目中用大强度大频率的方法测试时遇到sqlite报database is locked的问题,分析下来原因是sqlite对数据库做修改操作时会做(文件)锁使得其它进程同一时间使用时会报该错误( ...

  5. sqlite: Error Code : 5 (SQLITE_BUSY) (database is locked (code 5): , while compiling: PRAGMA journal_mode)

    今天遇到了一个很奇怪的问题,登录完成后,程序会莫名crash, 报了下面的错误: sqlite: Error Code : (SQLITE_BUSY) (database is locked (cod ...

  6. sqlite 报错:database is locked

    在sqlite批量添加数据时,报错:database is locked. 解决办法:将db路径由相对路径设置为绝对路径.

  7. 并发访问sqlite数据库出现databse is locked的错误的一个解决办法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 在并发访问sqlite数据库会出现这样一个错误:databseis locked,这是sqlite数据库对并发支持不太 ...

  8. svn: E200033: database is locked解决办法

    svn执行update,却被告知database is locked! 执行 svn update,却抛出个错误警报: svn: E200033: database is locked, execut ...

  9. Sqlite 数据库出现database disk image is malformed报错的解决方法

    软件用的是Sqlite数据库,昨天还好好的,今天开机登录软件报错:database disk image is malformed 用Sqlite Expert Personal 重建索引,发现其中一 ...

随机推荐

  1. HDU-4609(FFT/NTT)

    HDU-4609(FFT/NTT) 题意: 给出n个木棒,现从中不重复地选出3根来,求能拼出三角形的概率. 计算合法概率容易出现重复,所以建议计算不合法方案数 枚举选出的最大边是哪条,然后考虑剩下两条 ...

  2. Axure 部件的交互样式

    选中的 时  需要设置事件

  3. sql 实现分页+分组并取出分组内的前n条数据

    一.建表 if exists (select * from sysobjects where id = OBJECT_ID('[test]') and OBJECTPROPERTY(id, 'IsUs ...

  4. Network基础(二):数制转换

    一.数制转换 目标: 1)请将下列数字转换为十进制数: (110010011111)2 .(10110101110)2 2)请将下列十进制数转换为二进制: 156.2608.1043 方案: 使用按权 ...

  5. kubernetes集群中移除Node

    例如要在集群中移出node2节点1)在master节点上执行: kubectl drain node2 --delete-local-data --force --ignore-daemonsets ...

  6. POJ 3904 (莫比乌斯反演)

    Stancu likes space travels but he is a poor software developer and will never be able to buy his own ...

  7. 【Java架构:基础技术】一篇文章搞掂:Spring Boot 官方文档解读

    本文篇幅较长,建议合理利用右上角目录进行查看(如果没有目录请刷新). 本文内容大部分是翻译和总结官方文档,可以到https://docs.spring.io/spring-boot/docs查看(此地 ...

  8. Jquery 实现回车键触发功能

    keyup,上抬键盘 .$(function(){ 方法一: $(document).keyup(function(event){ if(event.keyCode ==13){ alert(&quo ...

  9. JS 判断是否为null

    1.判断undefined: var tmp = undefined; if (typeof(tmp) == "undefined"){ alert("undefined ...

  10. 建站手册-浏览器信息:Netscape 浏览器

    ylbtech-建站手册-浏览器信息:Netscape 浏览器 1.返回顶部 1. http://www.w3school.com.cn/browsers/browsers_netscape.asp ...