【问题标题】:QSqlDatabase concurrent queries in different threads不同线程中的QSqlDatabase并发查询
【发布时间】:2016-07-03 11:17:09
【问题描述】:

为了进行并发查询,我编写了以下代码。

QString databaseName = "DB-"+QThread::currentThread()->objectName();
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL",databaseName);
db.setHostName("192.168.1.2");
db.setDatabaseName("Behroozi");
db.setUserName("root");
db.setPassword("password");
db.open();

QSqlQuery query(db);
query.prepare("select * from Person where chatID=:chatID");
query.bindValue(":chatID",chatID);
if(query.exec())
    return true;    

db.close();
QSqlDatabase::removeDatabase(databaseName);

代码创建一个具有唯一名称的连接,打开它,进行查询,关闭它,最后删除连接。

问题是,它有内存泄漏。当我评论代码时,它不会泄漏。我还应该做些什么来防止它?

我写的代码安全吗?

如果我在 return 之前复制 db.close()removeDatabase,它将打印:

QSqlDatabasePrivate::removeDatabase: 连接 'DB-ReplyThread-1' 是 仍在使用中,所有查询都将停止工作。

【问题讨论】:

  • 你怎么知道它有内存泄漏? Process Explorer 下的内存使用量会增加吗?

标签: database multithreading qt memory-leaks


【解决方案1】:

当您在每个线程中创建新连接时,从 Qt 的角度来看它非常好,应删除与连接相关的查询对象,因此避免此消息的最简单方法如下:

 ....
do {
    QSqlQuery query(db);
    query.prepare("select * from Person        where chatID=:chatID");
    query.bindValue(":chatID",chatID);
    if(query.exec())
        break;    
} while (0);

db.close();

....    
  QSqlDatabase::removeDatabase(databaseName);

所以只要限制 QSqlQuery 的范围,然后在你关闭连接之前它就会被销毁。

【讨论】:

    【解决方案2】:

    引用documentation

    此外,查询存在时连接必须保持打开状态;否则,QSqlQuery 的行为是未定义的。

    因此您的代码必须在关闭数据库连接之前处理查询。这可能是你注意到的泄漏。


    另外请注意,您的数据库驱动程序可能不支持并发。我在某个地方读到过一些关于那个的东西,但现在想不起来了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多