从多个线程使用QSqlQuery

时间:2017-11-23 14:11:49

标签: multithreading qt c++11 qtsql

我运行了很多C ++ 11线程,这些线程在某些时候都需要数据库访问。主要是我做初始化数据库连接并打开数据库。 Qt文档说查询不是线程安全的,所以我使用全局互斥锁,直到线程内存在QSqlQuery。

这有效,但保证可以工作,还是在某个时候遇到问题?

3 个答案:

答案 0 :(得分:4)

看看Documentation告诉我们,

  

只能在创建连接的线程中使用连接。   在线程之间移动连接或从中创建查询   不支持不同的线程。

所以你确实需要每个线程一个连接。我通过基于线程生成动态名称来解决这个问题:

auto name = "my_db_" + QString::number((quint64)QThread::currentThread(), 16);
if(QSqlDatabase::contains(name))
    return QSqlDatabase::database(name);
else {
    auto db = QSqlDatabase::addDatabase( "QSQLITE", name);
    // open the database, setup tables, etc.
    return db;
}

如果您使用不由Qt管理的线程,请使用QThreadStorage为每个线程生成名称:

// must be static, to be the same for all threads
static QThreadStorage<QString> storage;

QString name;
if(storage.hasLocalData())
    name = storage.localData();
else {
    //simple way to get a random name
    name = "my_db_" + QUuid::createUuid().toString();
    storage.setLocalData(name);
}

重要提示: Sqlite可能会也可能无法处理多线程。见https://sqlite.org/threadsafe.html。据我所知,嵌入Qt的sqlite是线程安全的,因为这是默认的,我找不到任何在源代码中禁用它的标志。但是如果你使用的是不同的sqlite版本,那么shure它实际上支持线程。

答案 1 :(得分:1)

您可以使用SQL函数编写类,并使用signals-slots来执行查询并从数据库中获取结果。

它是线程安全的,也不需要使用mutex

答案 2 :(得分:-2)

你选择不好接近。应该使用共享的QSqlDatabase对象而不是QSqlQuery。请检查多线程数据库访问的next example。如果您不清楚,请告诉我。将解释更多。