2016-07-13 8 views
11

QMYSQLを使用してローカルデータベースに接続しています。アプリケーションは複数のスレッドで実行されます。各スレッドは、独立した接続を使用してデータベースに接続します。 Qtがデータベースに接続しようとすると、次のエラーが発生することがあります。どうしたの?Qt MySQLアダプタがランダムに接続を拒否する:MYSQLを割り当てることができません

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

データベース接続の作成に使用しているコードを表示できますか? – eclarkso

+1

@eclarkso私の質問が更新されました –

+1

すべてのスレッドで同じ接続名( "wsc")を使用しているようですが、その場合は注意を喚起する警告メッセージが表示されますスレッド接続は同時にアクティブです)。それは問題ではないことを確認するためにスレッドIDや何かを接続名に追加する価値がありますか?それがないと仮定して、あなたはQt MySQLプラグインをコンパイルしましたか、またはそれはいくつかのサードパーティから来ましたか?どのバージョンのMySQL? – eclarkso

答えて

9

利用可能であるあなたは、あなたの最後の更新の後に気にしないかもしれませんが、私はそれに基づいた理論を持っている:thisはありmysql_library_init()を示し、マルチスレッドアプリケーションではmain()から呼び出されます。

あなたはQt plugin sourceで見れば、その方法は、順番に、私はあなたの利用状況にaddDatabase()によって間接的に作成されますと信じてQMYSQLDriver : QSqlDriverコンストラクタから呼び出されqLibraryInit()、に包まれています。

MySQL docsmysql_library_init()は、QtSqlコードがすべてのQSqlDriver構造を保護することを必要とするミューテックスによって保護されている可能性があることに注意してください。だから私はこれがQtコードのバグかドキュメンテーションのギャップとみなされるかどうかはわかりません。

これはすべてあなたが記述した動作に適合しますが、私はまだ自分自身に疑問を抱いています - これが正しいと、より多くの人々がこの問題にぶつからず、SOや他のフォーラムでは明白ではありません。私はそれがメインスレッドの少なくともいくつかの初期の仕事に対して、産んだスレッドであなたの最初のDB活動を行うのは少し珍しいと思いますか?

+1

これはまさに失敗する理由であり、Qtのどこにも記載されていません。実際には –

+1

ありがとうございました。事実の後、https://bugreports.qt.io/browse/QTBUG-31468が見つかりました。https://bugreports.qt.io/browse/QTBUG-54872は、関連しているが別の問題として報告されました。 – eclarkso

-1

QtのQSqlDatabase :: isOpen()に関連するバグがあります。 http://bugreports.qt-project.org/browse/QTBUG-223

QSqlQuery :: lastError()は、QSqlQuery :: exec()経由のクエリが失敗した場合にエラーを表示するはずです。またQSqlDatabase ::いるisOpen()の接続、QSqlDatabaseの状態を報告する必要があります::最終エラーは()も

+1

このバグは無効です。そしてそれはQt3に関連しています、それはずっと前に非難されました。 Qt4でなくても。 –

関連する問題