I'm using QMYSQL to connect to a local database. The application runs over several threads. Each thread connects to database using an independent connection. Sometimes Qt throws following error when I try to connect to database. What's the problem?
QMYSQL: Unable to allocate a MYSQL object
Update
Added the code used to connect. This object is moved to a thread, the connection is named. critical
is a signal emitted to main window to terminate application execution after a critical error (showing a message). log
is a signal that is emitted to log incidences into database.
void ClientWorker::connect() {
m_database = QSqlDatabase::addDatabase("QMYSQL","wsc");
m_database.setHostName(m_host);
m_database.setDatabaseName(m_databaseName);
m_database.setPort(m_port);
m_database.setUserName(m_db_username);
m_database.setPassword(m_db_password);
if(!m_database.open()) {
QString error = "Unable to connect to database. Reason:\n";
error+= m_database.lastError().text();
log("Unable to connect to database! ", error, "ERROR" );
emit critical(tr("Database Error!"),error);
} else {
log("Connected to datbase successfully.", "", "NOTICE" );
}
Update 2
I just realized that every time a connection is made out of main thread, (with no active connections in main tread) the driver fails to load. I just added a small dummy connection code in main()
that connects and disconnects immediately (before any thread connects). Adding that code, everything works fine. I'm not sure why threads can't connect before a connection in main thread, but I think it looks like a bug. Hope this helps someone, Took 3 days of mine :/
You might not care after your last update, but I have a theory based on it: this indicates mysql_library_init()
has to be called from main()
for multithreaded applications.
If you look in the Qt plugin source, that method is wrapped in qLibraryInit()
, which is called from the QMYSQLDriver : QSqlDriver
constructors, which in turn I believe get created indirectly by addDatabase()
in your usage context.
The MySQL docs note that the mysql_library_init()
can be done protected by a mutex, which would entail the QtSql code protecting all QSqlDriver construction, which I don't think it does. So I'm not sure if this would be considered a Qt code bug or a gap in documentation.
This all fits the behavior you've described, but I'm still doubtful of myself - if this is correct it surprises me that more people haven't run into this and it's not more evident on SO and other fora. I guess it's a little unusual to do your first DB activity on a spawned thread vs. at least some initial work in the main thread?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With