Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QSql module and multithreaded application

I'm troubled by how the Sql module works with multithreaded application in Qt. http://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module clearly states that "A connection can only be used from within the thread that created it".

However this piece of code I wrote works :

#include <QCoreApplication>
#include <QSqlQuery>
#include <QtConcurrentRun>

void    req()
{
  QSqlQuery q("INSERT INTO users (username) VALUES (\"test\")");
}

void    db()
{
  QSqlDatabase _db;

  _db = QSqlDatabase::addDatabase("QMYSQL");
  _db.setDatabaseName("dbname");
  _db.setHostName("host");
  _db.setUserName("username");
  _db.setPassword("password");
  if (_db.open())
    std::cout << "Ok" << std::endl;
  else
    std::cout << "Error" << std::endl;
}

int     main(int ac, char **av)
{
  QCoreApplication app(ac, av);
  QtConcurrent::run(db);
  sleep(1);
  QtConcurrent::run(req);
  return app.exec();
}

My application design requires multiple threads to interact with a database. Thoses threads are spawned and managed by QtConcurrent::run().

So, since this piece of code works should I go for it or will I run into troubles doing that ?

Any help, documentation or explanation is welcome ! Thank you.

like image 238
Xaqq Avatar asked Sep 27 '11 09:09

Xaqq


1 Answers

The above code is fine because QSqlQuery creates its own QSqlDatabase. It would be a problem if it referenced _db as created by db(). The down side is that it doesn't actually do anything.

QSqlDatabase is not a QObject but it has-a driver which is a QObject and therefore has thread affinity.

If creating loads of QSqlDatabases is prohibitive, create worker threads which maintains their own connection. Then dispatch queries to these threads rather than creating new threads and therefore new connections.

like image 156
spraff Avatar answered Oct 06 '22 05:10

spraff