Deleting all objects in QThread if one of objects contain QSqlDatabase::addDatabase. How?
-
Hello all!
Updated with QSqlDatabase::addDatabase
I have this objects structure:
QThread |- Object1 |- Object2 |- Object3 |- Object3 |- ... |- ... |- ...
Object creation schema looks like:
QThread* oThread = new Qthread(); Object1* oObject1 = new Object1(); oObject1->moveToThread(oThread);
Inside of oObject1:
pSQL = QSqlDatabase::addDatabase("SQLITE",oDBName);
And this object keeps alive in thread and able to create some sub-objects of different types in this thread. One of objects contain QSqlDatabase::addDatabase(). The question is how to delete all of them correctly?
For now I have two ways of behaviour:- If I am parenting Object3 to Object2 it's crashed on exit application when the QThread quitting.
- If I am not parenting them all is quitting perfectly, but Object3 doesn't call ~Object3()
How objects have to be created and quitted if they are parenting object that is already in QThread?
How to delete whole objects tree at time of destroying QThread? -
As suggested by QThread::finished():
This signal can be connected to QObject::deleteLater(), to free objects in that thread.
-
@bogong said in Deleting all objects in QThread if one of objects contain QSqlDatabase::addDatabase. How?:
One of my objects contain QSqlDatabase::addDatabase assigned to property
Why? You should not do that (is also stated in the documentation).
"How to use QSqlDatabase::addDatabase properly in QThread and quit correctly?" - call it in the thread, but do NOT store it in a variable.
-
@jsulm ??? Why so? In every example that i found assigning:
- https://forum.qt.io/topic/24927/solved-qthread-and-qsqldatabase-example
- https://forum.qt.io/topic/77278/qsqldatabase-multiple-threads
- https://overcoder.net/q/1684904/использование-соединения-qsqldatabase-в-qtconcurrent-run-пул-псевдо-соединений
- https://coderoad.ru/23201320/qt-одновременных-MySQL-запросов-в-разных-потоках-сбой
Even official doc showing the same ...
-
@bogong https://doc.qt.io/qt-5/qsqldatabase.html
"Warning: It is highly recommended that you do not keep a copy of the QSqlDatabase around as a member of a class, as this will prevent the instance from being correctly cleaned up on shutdown. If you need to access an existing QSqlDatabase, it should be accessed with database(). If you chose to have a QSqlDatabase member variable, this needs to be deleted before the QCoreApplication instance is deleted, otherwise it may lead to undefined behavior."Which official examples do that?
-
@bogong said in Deleting all objects in QThread if one of objects contain QSqlDatabase::addDatabase. How?:
In every example that i found assigning:
You really should read those threads instead simply posting links. At least in 3 of the 4 it was mentioned/the solution to not store the QSqlDatabase instance as member!
-
@jsulm said in Deleting all objects in QThread if one of objects contain QSqlDatabase::addDatabase. How?:
Thx. I've got forgotten about difference between QSqlDatabase::addDatabase and QSqlDatabase::database. I have an application that hasn't been using threads. Everything in on thread - main. This application handling few standalone DBs based on SQLITE. And all have been working perfectly. Now I see where I am wrong.
What is the correct way if I want to handle multiple DBs in multiple threads?
Something like:QThread1 |- DB1 |- DB2 QThread2 |- DB3 QThread3 |- DB4
-
@bogong said in Deleting all objects in QThread if one of objects contain QSqlDatabase::addDatabase. How?:
What is the correct way if I want to handle multiple DBs in multiple threads?
Use distinct connection names and create the connections in the threads where you're going to use them (do not share same connection across threads).
-
@jsulm I mean what is the correct way to initiate DB by QSqlDatabase::addDatabase at first time? I understand that QSqlDatabase::database should be called from QThread. But where to initiate it? In main thread or it might be initiated anywhere? Do I need to do something additional to QSqlDatabase::addDatabase?
-
@bogong said in Deleting all objects in QThread if one of objects contain QSqlDatabase::addDatabase. How?:
But where to initiate it?
As I said: in the thread where you want to use the connection. I also already mentioned that you should NOT share db connections across different threads. So, create the connection in the thread where you want to use it and use this connection only in that thread...