QT Sqlite无法获取行。数据库已锁定。

4
我正在开发一款使用sqlite数据库的QT C++应用程序。表格使用QTableView和QSqlTableModel显示。有些表格大约有1万条记录。
我的问题是,当我尝试更新10K记录表中的任何一条记录时,会出现“数据库被锁定,无法获取行”错误。当记录数较少(比如20)时不会出现此问题。日志文件将被创建在应用程序文件夹中。似乎某个进程持有对数据库的锁定。无法找出实际原因。
有人能提供一些解决方法吗?
谢谢, Priyanka

有关条目数量,是否存在静态限制?当添加21个条目时会发生什么?它在哪里出现问题? - bobestm
一张表可以容纳的记录数量没有限制。对于记录较少的表,如果我执行更新查询,则会成功,而对于有10K条记录的表,数据库会被锁定。我还没有检查表不会被锁定的记录数量。我可以进行检查并回复您。 - Priyanka Bhatia
我认为这是您表格上的一般锁定问题,因为您有相当多的条目,在插入/更新(无论哪个)期间锁定表格需要很长时间,导致数据库在单个操作超过其内部超时等待(允许编写更改之前的时间),并出现此错误。您可以查看PRAGMA locking_mode = EXCLUSIVE. - Najzero
这条评论解决/回答了您的问题吗?一些反馈会很有用。 - bobestm
我已经了解了它,但不确定如何在QT中使用它。提供一个示例代码会很有帮助。 - Priyanka Bhatia
2个回答

5
在Qt中,您可以像这样向数据库发送PRAGMA:

dbObj = QSqlDatabase::addDatabase(...);
dbObj.setDatabaseName(...);
dbObj.open();   
dbObj.exec("PRAGMA locking_mode = EXCLUSIVE");

然而,我认为这不是你想要的。根据Qt文档:
驱动程序在执行select时被锁定更新。这可能会在使用QSqlTableModel时导致问题,因为Qt的项目视图按需要获取数据(在QSqlTableModel的情况下使用SqlQuery::fetchMore())。
看一下QSqlQuery::isActive,它说:
如果查询处于活动状态,则返回true。活动的QSqlQuery是已成功exec()但尚未完成的查询。当您完成活动查询时,可以通过调用finish()或clear()使查询不再活动,或者可以删除QSqlQuery实例。
关键是你有一个来自某个地方的阻塞查询,你需要正确地使其“不活动”或者你需要进行仲裁。

你最后关于"阻塞查询"的评论帮我解决了与QSqlDatabase相关的不同问题,因此你得到了+1。感谢(5年半之后)! - Rethunk

5

请检查您是否在另一个窗口中打开了sqlite数据库。我曾经遇到过同样的问题,但是后来发现我在数据库的另一个打开窗口中有未保存的更改。一旦关闭该实例,所有内容都将完美运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接