QSqlError(“5“, “Unable to fetch row“, “database is locked“)问题解决

文章分析了导致QSqlError错误‘5’,‘Unabletofetchrow’,‘databaseislocked’的原因,主要归咎于多线程并发写入数据库和事务处理不当。在事务中,开始和结束时的锁机制可能导致其他线程的写入冲突。解决方案包括减少事务使用,避免长时间持有锁,并进行老化测试以确保问题不再复现。

1. QSqlError(“5”, “Unable to fetch row”, “database is locked”)

下面是导致数据库丢失数据的原因分析,供参考。
参考:https://www.recoveryandmanagement.com/sqlite-database-disk-image-is-malformed/?spm=a2c5q.11423531.0.0.501c5097APVic1
注意:读数据库正常不代表写正常,博主曾遇到过数据库使用"insert"插入数据时报错但"select"查询是正常的。
确定数据库是否正常的方法是使用命令:

PRAGMA integrity_check;

但该命令比较耗时,如检查一个270w行数据的数据库耗时大概2.2秒;数据少会更快。

1.1 总结原因

    1. 多线程同时写数据库;当有事务产生时特容易出现该问题;
      原因:当前上锁逻辑是对数据库API上锁,即开启事务时上锁-事务开启处理完后解锁;插入数据上锁-数据插入执行完解锁;提交事务上锁-提交逻辑处理完解锁;事务处理过程有两次解锁都可能被其它线程去执行写入数据库,所以导致问题出现。
      另外下面的解释也可以说明事务容易导致异常:
      Begin tran付出的代价是在提交之前,所有SQL语句锁住的资源都不能释放,直到commit掉。可见,如果Begin tran套住的SQL语句太多,那数据库的性能就糟糕了。在该大事务提交之前,必然会阻塞别的语句,造成block很多。 Begin tran使用的原则是,在保证数据一致性的前提下,begin tran 套住的SQL语句越少越好!有些情况下可以采用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值