Адаптер Qt MySQL отказывается подключаться случайно: невозможно присвоить MYSQL

Я использую 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 дня:/

Ответ 1

Вам может не понравиться последнее обновление, но у меня есть теория, основанная на нем: this > указывает, что mysql_library_init() нужно вызывать из main() для многопоточных Приложения.

Если вы посмотрите в источник плагина Qt, этот метод завернут в qLibraryInit(), который вызывается из конструкторов QMYSQLDriver : QSqlDriver, который, в свою очередь, я считаю, что создается косвенно с помощью addDatabase() в контексте использования.

MySQL docs отмечают, что mysql_library_init() может быть защищен мьютексом, что повлечет за собой код QtSql, защищающий всю конструкцию QSqlDriver, что я не думаю, что это так. Поэтому я не уверен, что это будет считаться ошибкой кода Qt или пробелом в документации.

Все это соответствует поведению, которое вы описали, но я все еще сомневаюсь в себе - если это правильно, меня удивляет, что больше людей не сталкиваются с этим, и это не более очевидно на SO и других форумах. Я предполагаю, что немного необычно делать свою первую работу с БД на порожденном потоке по сравнению с некоторой начальной работой в основном потоке?

Ответ 2

В Qt есть ошибка, связанная с QSqlDatabase:: isOpen(). http://bugreports.qt-project.org/browse/QTBUG-223

QSqlQuery:: lastError() должен дать вам сообщение об ошибке, если ваш запрос через QSqlQuery:: exec() завершился с ошибкой. Также QSqlDatabase:: isOpen() должен сообщить о состоянии вашего соединения, QSqlDatabase:: lastError() также доступен