题目描述:
使用visual studio2022创建动态库,动态库中包含向sqlite3数据库插入数据的函数,在测试函数时偶然出现database is locked的错误提示。
思绪:
1、最开始以为是代码写的有题目,大概对于某些资源没有释放,经过检查后发现代码中某些情况下没有释放stmt,修改后重新测试依然没有解决题目。
2、后来根据locked想到了锁,那么是不是被程序中其他线程锁住了呢?很遗憾,我的程序是单线程的,并不是这个题目。
3、经过网上查询资料发现,依然有很大大概是被其他某个东西锁住了。不肯定是线程,也许是其他历程,于是发现了我另一个软件(sqlite expert)打开数据库文件后一直在监听数据,时不时会更新数据。那么会不会是因为这个软件一直在监听数据导致的呢?但是很奇怪的是,这个软件只是读数据,而不会去写数据,真的是这个软件导致的题目吗?
题目缘故原由
经过查询sqlite3的锁机制发现:sqlite3并不支持并发写,在某一时刻只能有一个毗连去写数据。
sqlite3的锁包含五种状态:未加锁、共享锁、保留锁、未决锁、排他锁。
起首,当全部的毗连都没有毗连到数据库时,处于未加锁状态;
其次,当某个毗连试图去读取数据库数据时,此时处于共享锁状态,此时依然允许其他毗连申请共享锁;
接着,当某个毗连试图去写数据时,须要申请保留锁,意味着该毗连已经准备好写数据了(但还没写),此时依然允许有毗连申请共享锁;
最后,试图写数据的毗连须要获取写锁,由于sqlite3只允许一个线程写入数据,因此须要将保留锁升级成排他锁,从而写入数据。而当它试图升级为排它锁但还没得到时,则先将锁升级为未决锁,此时将不再允许有新的毗连得到共享锁,当全部的已经得到共享锁的毗连读取完数据释放共享锁后,此时试图写入数据的毗连将未决锁升级成排它锁,从而写入数据。
总结
那么此时回看之前的题目,由于sqlite expert会时不时自动刷新数据,因此,当sqlite expert没有对数据进行刷新时,数据可以正常的插入数据库文件中,但是当sqlite expert刷新数据时,就会导致database is locked,因为只要有一个毗连持有共享锁,都无法写入数据。这也是为什么偶然该错误的缘故原由。后来将sqlite expert换成了sqlite studio,sqlite studio不会自动刷新数据,须要手动点击刷新按钮才会刷新数据,因此用sqlite studio打开数据库文件并没有出现类似的题目(不要在连续插入数据时点击刷新数据的按钮,否则也会出现上述题目)。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |