不知道大家注意到没,这段时间,我的BLOG总是不断出现 This Database is Locked
的现象,回复留言极其痛苦,今天解决了这个问题,在这里给出这个问题的原因和解决过程
我的问题主要是下面Sqlite的知识点所说的问题
多进程可以同时打开同一个数据库,也可以同时 SELECT 。但只有一个进程可以立即改数据库。
Win95/98/ME 操作系统缺乏读书锁定,在低于 2.7.0 的版本中,这意味着在 windows下在同一时间内只能有一个进程读数据库。在版本 2.7.0 中这个问题通过在 windows接口代码中执行一个用户间隔几率读写锁定策略解决了。Windows 现在像 Unix 一样允许并发读取了。
如果数据库文件在一个 NFS 文件系统中,控制并发读书的锁定机制可以会出错。因为 NFS的锁定有时会坏掉。如果有多进程可以并发读书数据库则因当避免把数据库文件放在 NFS 文件系统中。根据微软的文档,如果不运行 Share.exe守护程序则 FAT 文件系统中的锁定可能不工作。对 Windows非常有经验的人告诉我网络文件的锁定有许多问题并且不可靠。如果是这样在二个或以上 Windows 系统中共享一个 SQLite数据库文件会导致不可预知的问题。
SQLite 的锁定是数据库级的,而大型数据库服务(如 PostgreSQL, Oracle 等等) 通常有更好的锁定,如锁定一个表或一记录。如果你的程序有大量并行操作建议使用大型数据服务。
当 SQLite 尝试操作一个被另一个进程锁定的文件时,缺省的行为是返回 SQLITE_BUSY。在 C代码中你可以通过使用sqlite3_busy_handler() 或 sqlite3_busy_timeout() API函数来调整这个缺省行为。详见 API 文档。
如果两个或更多进程同时打开同一个数据库,其中一个进程创建了新的表或索引,则其它进程可能不能立即看见新的表。其它进程可能需要关闭并重新连结数据库。
问题找到了,因为当我在 Insert 数据的时候,先前的 SELECT 操作没有关闭数据库的连接,而导致数据库被锁定,马上加上关闭,重新连接的方式, 但速度还是有问题,在仔细研究了一段 Sqlite 的实例代码后,发现它采用了事务的写法,马上采用,果然,问题得到解决。
PS:因为是个人BLOG,我偷懒,在读取的循环中输出到页面,这样在过程中也容易锁死数据库,更合理的做法是:读取到 DataSet 或者实体类集合再输出。
还有一个让人郁闷的事情就是,Sqlite的英文站点地址是: http://sqlite.org ,习惯性的打开 http://sqlite.org.cn ,看是不是中文支持站点,但发现这个站点居然是一个垃圾站点(诱惑类的图片站点),仔细查询了这个网站的历史,这个网站早期也是一个关于 Sqlite 的站点,只是后来转变成了这么一个垃圾站点,哎~这类网站有“钱途”啊~~
> 可在 Twitter/X 上评论该篇文章或在下面留言(需要有 GitHub 账号)