sql query thread termination
-
Hi,
I have a lengthy queries that I execute in a separate thread to keep the UI responsive.I read forum posts and opinions that feeding QsqlQueryModel/QSqlQuery from thread to mainapp is not recommended solution.
So instead I execute the query in the thread and create a QVariantMap that is sent as signal argument when read and can be picked up by mainWindow slot that will convert the QVariantMap into QStandardItemModel and then to QTableView.I also have a button that allows the user to terminate the thread if user is impatient.
So in the thread's run() I do
QSqlQuery query(threadDB); query.prepare(queryString); setQueryBinds(query, queryBinds); result = query.exec(); QVariantMap results; // Create a map to store extracted data QStringList headers; for (int i = 0; i < query.record().count(); ++i) { headers.append(query.record().fieldName(i)); } results.insert("headers", headers); int rowCount = 0; while (query.next()) { QVariantMap row; for (int i = 0; i < query.record().count(); ++i) { QString columnName = query.record().fieldName(i); QVariant columnValue = query.value(i); row.insert(columnName, columnValue); } results.insert(QString::number(rowCount), row); ++rowCount; } if (!isInterruptionRequested()) emit queryExecutionFinished(results); // Emit the signal with the results
and in my mainWindow uses
void iSqlManager::abortQuery() { qDebug()<<Q_FUNC_INFO; if (execThread && execThread->isRunning()) { execThread->requestInterruption(); // Safer way to signal the thread to stop // execThread->terminate(); execThread->wait(); queryAbortButton->setText("Anulowano zapytanie"); emit queryAborted(); emit errorOccurred("Anulowano zapytanie."); // execThread->deleteLater(); } }
The problem is that if i call abortQuery() no matter if I call requestInterruption() or terminate() the query keeps running and running .
to avoid race conditions I want the app to be able to have only one sql thread running so in the preparation for execution of query i check there's no other thread already
if (execThread && execThread->isRunning()) { QString error = "Another query is already running."; emit errorOccurred(error); qDebug()<<error; return; }
If the abortQuery does not terminate the thread effectively the user has to wait until query is fetched even if he decided to cancel the execution with the abort button.
What is the proper way to terminate the query execution and generation of results ?
-
@Seb-Tur said in sql query thread termination:
requestInterruption()
But you don't check for it in your thread.
-
I do below
if (!isInterruptionRequested()) emit queryExecutionFinished(results); // Emit the signal with the results
but my question is how do I kill the thread stuck at the query.exec() ?
-
@Seb-Tur said in sql query thread termination:
I do below
if (!isInterruptionRequested())
emit queryExecutionFinished(results); // Emit the signal with the resultsYou should do inside the query.next() when there are a lot of rows.
but my question is how do I kill the thread stuck at the query.exec() ?
simply exit the run() function.