解决SQLite database is locked

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

  Sqlite的特色:web

  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的文件锁来实现库级锁,粒度很大,可是,它经过一些复杂特殊的处理(具体能够参见分析系列),尽可能的提高了读写的并发度。若是你还有担忧,你能够看看这篇文章:http://www.dbanotes.net/database/sqlite_cms.html
  5. SQL92:SQLite支持绝大部分的标准SQL语句,你只须要几百K的空间,就能够换来须要上百兆的通用DBMS几乎全部操做了。
  6. 方便(Convenience):若是你的程序要使用SQLite,只须要将拷贝你的程序目录便可。
  7. 开源(Opensource):这是它最强大的地方。开源,意味着你能够品读它的源码,你能够随时修改它,加入你本身的特性,而这一切彻底免费的。开源,是一种精神

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

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

  测试程序以下:小程序

  Main( ( i = ; i < ; i++= =  +   flag =  ( sql =  + id.ToString() + =  sql =  + id.ToString() + =

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

  解决办法:并发

    obj =     ExecuteNonQuery(= = (SQLiteConn.State != result =
事实证实Sqlite不支持并发执行写入操做,即便是不一样的表,只支持库级锁,并且这个Sqlite自己没有实现,必须本身实现这个库级锁。
相关文章
相关标签/搜索