Important: Please read the Qt Code of Conduct -

The right way to use QtSqlDatabase across multiple threads

  • Hello,

    It's being two days that I am trying to make a multithreaded application that need to collect data from several databases.
    I tried to make a QRunnable + QThreadPool but I get an first chance access violation when calling QSqlDatabase::open() on a db created in the QRunnable::run(). After this failed I tried to use Worker-Object+QThread this option work, but I didn't figure out how to put the thread on sleep when data collection is done (I collect data every 30m).
    I need to know about the correct and the right way to use QSqlDatabase across multiple threads.

  • Could you post your worker+thread solution?

  • Lifetime Qt Champion


    To add to @VRonin, one thing you have to do is to name your connection on a per thread basis. Otherwise you'll have threads starting more or less at the "same time" thus trying to use the default connection and therefore shooting at each other.

  • I agree with you on naming connection which I did, every thread is using his unique connection name.
    Worker object:

    class AgencyMasterInfoFetcher: public QObject {
        QSqlDatabase* _db;
        bool _cant_fetch;
        explicit AgencyMasterInfoFetcher(QSqlDatabase* db, QObject* parent = nullptr);
    public slots:
        void fetch();
        void stop();
        void closing();
        void fetched(AgencyMaster);
        void error(QString);


    void AgencyMasterInfoFetcher::fetch()
        if(_cant_fetch) return;
        if(!_db->isOpen()) if(!_db->open()) { 
    emit error(QString{"Couldn't connect to the database"}); qDebug() << "Done fetching"; return; }
        _cant_fetch = true;
    // fetching some data
        emit fetched(agency);
        _cant_fetch = false;
    void AgencyMasterInfoFetcher::stop()
        emit closing();

    starting threads from main.cpp

    int main() {
      QVector<QThread*> threads {};
      for (int i = 0; i < dbs.size(); i++) threads << new QThread();
      QVector<AgencyMasterInfoFetcher*> workers{};
      for (int i = 0; i < dbs.size(); i++) {
          workers << new AgencyMasterInfoFetcher(&dbs[i]);

  • LGTM

    Probably just worth telling us how you create dbs

    I collect data every 30m

    Just have your agencies emit needData every 30 minutes

  • Sorry I forget about it and it's the main concerne :p
    dbs is QVector<QSqlDatabase> created in the main fonction with calls to QSqlDatabase::addDatabase("QODBC3","agency1") the connection name will vary (agency1,agency2,....etc)

Log in to reply