QxOrm with threads

Forum for posting problems using QxOrm library

QxOrm with threads

Postby gigigi2002 » Mon Jun 01, 2020 1:57 pm

Hello,
I am using the latest QxOrm 1.4.7 and Qt 5.12 with MySQL database.
The application setting up all necessary parameters for working with database in the main thread.
When user opens up a panel there is a worker thread created which will be used to access the database, depending on user actions on that panel.
When user opened up a panel first time everything seem to work well. QxOrm creating a new connection to the database, query to the database is complete and thread is quit.
Then the panel is closed, so the thread is destroyed.
When user opens up the same panel again a new worker thread is created. This time an attempt to communicate with the database failed with an error:

    QSqlDatabasePrivate::database: requested database does not belong to the calling thread.
    [QxOrm] 'qx::dao' internal error <fetch all>
    [QxOrm] error retrieving valid sql connection to database

Further investigation showed that every time user opens up a panel the worker thread created with the same threadID.
QxSqlDatabase class is tracking connections based on threadID while QSqlDatabase class checks the actual Thread pointer in order to track thread specific connections:
Code: Select all
if (db.driver()->thread() != QThread::currentThread()) {
        qWarning("QSqlDatabasePrivate::database: requested database does not belong to the calling thread.");
        return QSqlDatabase();
    }


So, when the user attempts to open a panel second time the connection doesn't exist anymore as thread is different (though it has the same threadID) and QSqlDatabase::database() call returns an empty object.
At the same time internal m_lstDbByThread list will still hold a trace of non existing connection.

Looking through various forums a possible solution would be to use QSqlDatabase::removeDatabase(const QString& connectionName) to remove existing connection.
Please confirm if that is the case?
But it has to be done in the thread itself and it won't clean the record from m_lstDbByThread list.

Looking through the code of QxSqlDatabase, another possible solution could be calling QxSqlDatabase::clearCurrentDatabaseByThread() but this is a protected method in QxSqlDatabase class.

Would it make sense to track the thread inside of QxOrm based on QThread::currentThread() method rather than threadID similar to how it is done in the Qt code? Perhaps this is not done based on threadID as the same ID can be re-used for different threads.

I expect that one may suggest to keep the worker thread running forever, without starting/stopping. Which might be a good idea or I can use QtConcurrentRun or QThreadPool but there is also a requirement to be able to cancel the operation in the middle of long multiple readins/writings to the database which is difficult to achieve using QtConcurrent or QtThreadPool. That would be a main reason why I have to use existing model of running a worker thread created by a panel where both can be closed depending on user action.

What would be a recommended solution in my scenario?
gigigi2002
 
Posts: 2
Joined: Mon Jun 01, 2020 1:15 pm

Re: QxOrm with threads

Postby qxorm » Mon Jun 01, 2020 2:33 pm

Hello,

I don't know about your "panel", but creating a new thread with same ID each time looks strange :)

As you said, I think the solution is to use QSqlDatabase::removeDatabase closing your panel / destroying worker thread :
Code: Select all
QSqlDatabase::removeDatabase(const QString& connectionName)


I checked QxOrm source code and it should work because even if thread ID exists in m_lstDbByThread variable, there is a double-check with :
Code: Select all
QSqlDatabase::contains(sDbKey)
qxorm
Site Admin
 
Posts: 481
Joined: Mon Apr 12, 2010 7:45 am


Return to QxOrm - Help

Who is online

Users browsing this forum: No registered users and 3 guests

cron