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