Problems with Open-Source Downloads read https://www.qt.io/blog/problem-with-open-source-downloads and https://forum.qt.io/post/638946

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?


  • Qt Champions 2017

    @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?


  • Lifetime Qt Champion

    @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?


  • Qt Champions 2017

    @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?


Log in to reply