我正在使用QMYSQL连接到本地数据库。应用程序在多个线程上运行。每个线程使用独立的连接连接到数据库。有时Qt在我尝试连接到数据库时会抛出以下错误。怎么了?
QMYSQL: Unable to allocate a MYSQL object
更新
添加了用于连接的代码。此对象被移动到线程,连接被命名。 critical
是发送到主窗口的信号,用于在发生严重错误(显示消息)后终止应用程序执行。 log
是发出以将事件记录到数据库中的信号。
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" );
}
更新 2
我刚刚意识到每次从主线程建立连接时,(主胎面中没有活动连接)驱动程序无法加载。我刚刚在 main()
中添加了一个小的虚拟连接代码,它立即连接和断开连接(在任何线程连接之前)。添加该代码,一切正常。我不确定为什么线程在主线程连接之前无法连接,但我认为这看起来像一个错误。希望这对某人有所帮助,花了我的 3 天:/
更新后你可能不在乎,但我有一个基于它的理论:这表明mysql_library_init()
必须从多线程应用程序的main()
调用。
如果您查看Qt插件源代码,该方法包装在qLibraryInit()
中,这是从QMYSQLDriver : QSqlDriver
构造函数调用的,而我认为这些构造函数又是通过在您的使用上下文中addDatabase()
间接创建的。
MySQL文档指出,mysql_library_init()
可以通过互斥锁进行保护,这将需要QtSql代码保护所有QSqlDriver构造,我认为它没有。 所以我不确定这是否会被视为Qt代码错误或文档中的空白。
这一切都符合您描述的行为,但我仍然怀疑自己 - 如果这是正确的,我很惊讶更多的人没有遇到这种情况,并且在 SO 和其他论坛上并不明显。 我想在生成的线程上执行第一个数据库活动与在主线程中进行至少一些初始工作相比有点不寻常?
Qt中有一个与QSqlDatabase::isOpen()相关的错误。http://bugreports.qt-project.org/browse/QTBUG-223
QSqlQuery::lastError() 应该会给你一个错误,如果你通过 QSqlQuery::exec() 查询失败了。此外,QSqlDatabase::isOpen() 应该报告您的连接状态,QSqlDatabase::lastError() 也可用