Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. The right way to use QtSqlDatabase across multiple threads
Forum Updated to NodeBB v4.3 + New Features

The right way to use QtSqlDatabase across multiple threads

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 2.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    batcher
    wrote on last edited by
    #1

    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.

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2

      Could you post your worker+thread solution?

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        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.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • B Offline
          B Offline
          batcher
          wrote on last edited by batcher
          #4

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

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

          Implementation

          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()
          {
              _db->close();
              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]);
                workers[i]->moveToThread(threads[i]);
                QObject::connect(agencies[i],SIGNAL(needData()),workers[i],SLOT(fetch()),Qt::QueuedConnection);
                QObject::connect(workers[i],SIGNAL(fetched(AgencyMaster)),agencies[i],SLOT(setData(AgencyMaster)),Qt::QueuedConnection);
                QObject::connect(workers[i],SIGNAL(error(QString)),agencies[i],SLOT(error_fetching(QString)),Qt::QueuedConnection);
                QObject::connect(workers[i],SIGNAL(closing()),threads[i],SLOT(quit()),Qt::QueuedConnection);
                QObject::connect(threads[i],SIGNAL(finished()),workers[i],SLOT(deleteLater()),Qt::QueuedConnection);
                QObject::connect(threads[i],SIGNAL(finished()),threads[i],SLOT(deleteLater()),Qt::QueuedConnection);
                threads[i]->start();
            }
          }
          
          1 Reply Last reply
          0
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #5

            LGTM

            Probably just worth telling us how you create dbs

            I collect data every 30m

            Just have your agencies emit needData every 30 minutes

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            1 Reply Last reply
            0
            • B Offline
              B Offline
              batcher
              wrote on last edited by
              #6

              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)

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved