У меня есть два подключения к базе данных QSqlDatabase: «локальное» и «удаленное». У меня есть функция, которая использует оба соединения (получает данные из локальной базы данных и отправляет на удаленную базу данных). Когда я запускаю эту функцию из своего класса QThread, локальное соединение работает (я получил ожидаемые данные), но удаленное соединение не работает. Но если я запускаю эту функцию вне класса QThread (в main()), работают оба соединения.
Удаленное соединение завершается сбоем, когда я пытаюсь открыть соединение с сообщением об ошибке: «QSqlDatabasePrivate::database: невозможно открыть базу данных: QMYSQL: невозможно подключиться». Перед этим я проверил, действительно ли соединение (isValid()), и оно было в порядке. Я также проверяю, было ли уже открыто соединение, но это не так.
Я также нашел эту информацию, но поскольку «локальное» соединение работает из потока, это может быть не проблема:
Потоки и модуль SQL. Соединение можно использовать только из создавшего его потока. Перемещение соединений между потоками или создание запросов из другого потока не поддерживается. http://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module
Ошибка обнаружена в Qt 5.5.1, 32bit, Ubuntu 14.04. Также тестировался на Raspberry Pi, Qt 5.6, но в результате "ошибка сегментации".
Что не так?
main.c
main()
{
DataHandler dh();
DataHandlerThread dht(&dh); //pointer to dh to get access to dh functions from the thread
//here I run dh.foo() or dht.run(), never both functions
dh.foo();
dht.run();
...
}
datahandler.cpp
DataHandler::DataHandler()
{
m_dbLocal = QSqlDatabase::addDatabase("QMYSQL", "local");
m_dbLocal.setHostName("localhost");
...
m_dbRemote = QSqlDatabase::addDatabase("QMYSQL", "remote");
m_dbRemote.setHostName(...);
...
}
DataHandler::foo()
{
qDebug() << QSqlDatabase::connectionNames(); //always ("remote", "local")
m_dbLocal.isValid(); //always true
m_dbLocal.open(); //always true
m_dbRemote.isValid(); //always true
//true if foo() is called from main using dm.foo()
//QSqlDatabasePrivate::database: unable to open database: " QMYSQL: Unable to connect" if called from main using dmt.run()
m_dbRemote.open();
}
datahandlerthread.h
class DataHandlerThread : public QThread
{
Q_OBJECT
public:
explicit DataHandlerThread(DataHandler* dh);
private:
void run() Q_DECL_OVERRIDE;
DataHandler* m_dh;
};
datahandlerthread.cpp
DataHandlerThread::DataHandlerThread(DataHandler* dh)
{
m_dh = dh;
}
void DataHandlerThread::run()
{
m_dh->foo();
}