QSqlDatabase don't close automatically
-
The doc says: (http://doc.qt.io/qt-5/qsqldatabase.html#dtor.QSqlDatabase)
"When the last connection is destroyed, the destructor implicitly calls close() to release the database connection."I thought that as long as I only create local instances of QSqlDatabase, I don't need to call close() manually. However, one day I found that my app is always connected to the database, so I created a simple test:
#include <QSqlDatabase> #include <QDebug> int main(int argc, char *argv[]) { { QSqlDatabase dbIn = QSqlDatabase::addDatabase("QMYSQL", "test"); dbIn.setHostName("localhost"); dbIn.setPort(3306); dbIn.setUserName("username"); dbIn.setPassword("password"); dbIn.setDatabaseName("database"); dbIn.open(); qDebug() << dbIn.isOpen(); } QSqlDatabase dbOut = QSqlDatabase::database("test", false); qDebug() << dbOut.isOpen(); return 0; }
and it prints "true true".
I'm using Qt 5.11.2 MinGW. Is it a bug, or maybe I misunderstood the doc?
-
@Sentret_C said in QSqlDatabase don't close automatically:
I thought that as long as I only create local instances of QSqlDatabase, I don't need to call close() manually.
Nope. This would imply, beside other things, that every time you call
QSqlDatabase::database
a new connection is to be created.QSqlDatabase
is a value object, you need to remove the connection from the global registry for the database to be actually closed. -
@kshegunov said in QSqlDatabase don't close automatically:
remove the connection from the global registry
You mean by calling QSqlDatabase::removeDatabase? What about the sentence I quoted?
"When the last connection is destroyed, the destructor implicitly calls close() to release the database connection."
Under what circumstances will the destructor implicitly call close()?I made the test clearer:
#include <QSqlDatabase> #include <QDebug> void addAndOpen(QString connectionName) { QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", connectionName); db.setHostName("localhost"); db.setPort(3306); db.setUserName("username"); db.setPassword("password"); db.setDatabaseName("database"); db.open(); qDebug() << db.isOpen(); } void check(QString connectionName) { QSqlDatabase db = QSqlDatabase::database(connectionName, false); qDebug() << db.isOpen(); } int main(int argc, char *argv[]) { addAndOpen("test"); check("test"); return 0; }
Before calling check(), the last connection is destroyed, right?
-
@Sentret_C said in QSqlDatabase don't close automatically:
When the last connection is destroyed
You destroy the last conection when you call QSqlDatabase::removeDatabase()
-
I read the source code and finally realized that a copy of the QSqlDatabase instance is stored in the global static object dbDict when QSqlDatabase::addDatabase is called, and that instance is the last connection, destroyed in QSqlDatabase::removeDatabase.
Is that right?
BTW, I'm working on an app which interacts with the database about once a second. Should I close the connection everytime the (group of) query is finished? What if the interaction is more or less often?
-
@Sentret_C said in QSqlDatabase don't close automatically:
Should I close the connection everytime the (group of) query is finished?
Of course not. That's why you have a "connection" to the database - to keep it alive as long as needed. What would be the point of closing and reopening it every time? Say you are reading a book, do you close the book after you read a passage and then reopen it again so you can read the next one?