2016-07-13 9 views
11

Ich verwende QMYSQL, um eine Verbindung zu einer lokalen Datenbank herzustellen. Die Anwendung läuft über mehrere Threads. Jeder Thread stellt mithilfe einer unabhängigen Verbindung eine Verbindung zur Datenbank her. Manchmal gibt Qt einen Fehler aus, wenn ich versuche, eine Verbindung zur Datenbank herzustellen. Was ist das Problem?Qt MySQL-Adapter verweigert die Verbindung nach dem Zufallsprinzip: Konnte keine MYSQL zuordnen

QMYSQL: Unable to allocate a MYSQL object 

aktualisieren

Added der Code verwendet zu verbinden. Dieses Objekt wird in einen Thread verschoben, die Verbindung wird benannt. critical ist ein Signal, das an das Hauptfenster gesendet wird, um die Ausführung der Anwendung nach einem kritischen Fehler (der eine Nachricht anzeigt) zu beenden. log ist ein Signal, das ausgegeben wird, um Vorfälle in die Datenbank zu protokollieren.

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

Ich habe erkannt, dass jedes Mal eine Verbindung von Hauptgewinde ist (ohne aktive Verbindungen in Hauptlauffläche) der Treiber nicht geladen werden kann. Ich habe gerade einen kleinen Dummy-Verbindungscode in main() hinzugefügt, der sofort verbindet und trennt (bevor jeder Thread verbindet). Wenn Sie diesen Code hinzufügen, funktioniert alles einwandfrei. Ich bin mir nicht sicher, warum Threads vor einer Verbindung im Hauptthread keine Verbindung herstellen können, aber ich denke, es sieht wie ein Bug aus. Hoffe, das hilft jemandem, dauerte 3 Tage von mir:/

+1

Können Sie den Code anzeigen, den Sie zum Erstellen der Datenbankverbindungen verwenden? – eclarkso

+1

@eclarkso Aktualisiert meine Frage –

+1

Es sieht so aus, als ob Sie den gleichen Verbindungsnamen ("Wsc") über alle Ihre Threads verwenden - aber in diesem Fall würde ich eine merkliche Warnmeldung erwarten, die Ihre Aufmerksamkeit erregt hätte (vorausgesetzt, anders Thread-Verbindungen sind gleichzeitig aktiv)? Könnte es sinnvoll sein, die Thread-ID oder etwas an den Verbindungsnamen anzuhängen, um sicherzustellen, dass das nicht das Problem ist? Angenommen, es ist nicht, haben Sie das Qt MySQL-Plugin kompiliert oder stammt es von einem Drittanbieter? Welche Version von MySQL? – eclarkso

Antwort

9

Sie werden vielleicht nicht nach der letzten Aktualisierung kümmern, aber ich habe eine Theorie darauf basierenden: this zeigt mysql_library_init() hat von main() für Multithread-Anwendungen aufgerufen werden.

Wenn Sie in den Qt plugin source aussehen, wird diese Methode in qLibraryInit() gewickelt, die sie von dem QMYSQLDriver : QSqlDriver Bauer genannt wird, was wiederum ich von addDatabase() in Ihrem Nutzungskontext indirekt erhalten erstellt glauben. Die MySQL docs Die MySQL docs beachten, dass die mysql_library_init() geschützt durch einen Mutex erfolgen kann, was den QtSql-Code beinhalten würde, der alle QSqlDriver-Konstruktionen schützt, was ich nicht glaube. Ich bin mir also nicht sicher, ob dies als Qt-Code-Bug oder als Lücke in der Dokumentation betrachtet wird.

Das passt alles zu dem Verhalten, das Sie beschrieben haben, aber ich zweifle immer noch an mir selbst - wenn das stimmt, überrascht es mich, dass mehr Leute nicht auf dieses Problem gestoßen sind und es auf SO und anderen Foren nicht deutlicher ist. Ich denke, es ist ein wenig ungewöhnlich, deine erste DB-Aktivität auf einem erstellten Thread zu betreiben, im Gegensatz zu einer anfänglichen Arbeit im Hauptthread?

+1

Dies ist genau der Grund zum Scheitern, und nein, es ist nirgends in Qt dokumentiert. Danke –

+1

Gefunden https://bugreports.qt.io/browse/QTBUG-31468 nach der Tat, und berichtete https://bugreports.qt.io/browse/QTBUG-54872 als eine verwandte, aber separate Problem. – eclarkso

-1

Es gibt einen Fehler im Zusammenhang mit QSqlDatabase :: isOpen() in Qt. http://bugreports.qt-project.org/browse/QTBUG-223

QSqlQuery :: lastError() sollte Ihnen einen Fehler geben, wenn Ihre Abfrage über QSqlQuery :: exec() fehlgeschlagen ist. QSqlDatabase auch :: isOpen(), um den Zustand Ihrer Verbindung mitteilen, QSqlDatabase :: lasterror() ist ebenfalls verfügbar

+1

Dieser Fehler wird als ungültig geschlossen. Und es ist verwandt mit Qt3, das vor langer Zeit veraltet war. Auch nicht Qt4. –