QSqlDatabase Transactions、QSqlQuery Creation 和 QSqlQuery 完成

Posted

技术标签:

【中文标题】QSqlDatabase Transactions、QSqlQuery Creation 和 QSqlQuery 完成【英文标题】:QSqlDatabase Transactions,QSqlQuery Creation and QSqlQuery finish 【发布时间】:2013-08-19 04:49:28 【问题描述】:

我注意到QSqlDatabase 文档说

"注意:使用事务时,必须在创建查询之前启动事务。"

如果您必须在启动事务后才创建查询,这是否会限制 QSqlQuery::prepare() 在事务情况下的有用性?已向here 提出了相同的问题...但没有提供令人满意的答案。

我的另一个问题是,如果您使用QSqlQuery::prepare() 准备查询并调用QSqlQuery::finish(),是否应该再次准备查询?我问这个是因为在文档中没有提到准备好的查询以防万一QSqlQuery::finish()。

【问题讨论】:

创建QSqlQuery和启动事务的顺序没有区别。如果您查看幕后代码,创建 QSqlQuery 对象并不涉及与 DBE 通信。我认为他们指的是 SQL 查询的执行,而不是 QSqlQuery 对象的创建。 @RobbieE,感谢您的评论 【参考方案1】:

事务的要点是能够执行几个不同的查询,其中只有在一切正常的情况下才会提交数据库更改。

考虑以下代码结构(伪代码):

startTransaction()
try

    insertParentDataset(parent);
    insertChildDataset(child1);
    insertChildDataset(child2);
    commitTransaction();

catch

    rollbackTransaction()

这样结构的代码将确保每个查询只有在前一个查询有效的情况下才会执行,并且在任何错误的情况下,try 块中的方法造成的每个更改都将被忽略,即数据库仍将处于与以前相同的状态。

出于这些原因,我只在修改数据库时使用事务,而不是在读取数据库时使用。

准备或不准备查询的决定是完全不同的事情。您通常准备查询以提高大量数据插入的性能或防止用户进行 SQL 注入(可能有更多原因),但这不会影响事务的行为。从事务的角度来看,执行“正常”查询或准备好的查询都没有关系。

关于finish(),我从未使用过。不同的查询使用不同的 QSqlQuery 对象通常会更方便。

【讨论】:

感谢您的评论。 1)“我只在修改数据库时使用事务,而不是在读取它们时。”我想何时使用事务的决定有时也取决于数据库驱动程序!例如在 Sqlite 中,如果有多个 select 语句要执行,出于性能原因,最好将它们包装在事务中。有关详细信息,请参阅this question。 2)"Concerning finish()" :如果需要一次又一次地执行相同的查询,那么我像this 一样准备一次查询,然后我可以多次使用它。但是如果查询返回一个大数据集,那么我可能不得不使用 finish() 来释放资源。在这种情况下,我想知道是否必须再次准备查询。 那么您可能对this question and answer 感兴趣。 感谢您的链接。它帮助了我。我在 sqlite 数据库上测试了查询,我能够每秒执行 10 万次插入,而没有任何内存问题。由于提供的链接而接受答案。

以上是关于QSqlDatabase Transactions、QSqlQuery Creation 和 QSqlQuery 完成的主要内容,如果未能解决你的问题,请参考以下文章

QSqlDatabase open 更新后总是返回true

QSqlDatabase:无法使用来自 QThread 的连接

ubuntu下qt5和数据库连接失败,报错QSqlDatabase: QMYSQL driver not loaded QSqlDatabase: available drivers: QSQLITE

PyQt5 QSqlDatabase 在没有任何文本错误的情况下无法打开

QSqlDatabase:Mac OS 上未加载 QMYSQL 驱动程序

QSqlDatabase 并连接到 .sqlite 文件