Fix "database is locked" errors caused by concurrent writes

This commit is contained in:
Bart De Vries 2022-07-14 15:32:58 +02:00
parent 338e73a8ab
commit c3df8d8714
2 changed files with 11 additions and 1 deletions

View File

@ -171,7 +171,11 @@ bool Database::execute(QSqlQuery &query)
bool Database::transaction(const QString &connectionName)
{
return QSqlDatabase::database(connectionName).transaction();
// use IMMEDIATE transaction here to avoid deadlocks with writes happening
// in different threads
QSqlQuery query(QSqlDatabase::database(connectionName));
query.prepare(QStringLiteral("BEGIN IMMEDIATE TRANSACTION;"));
return execute(query);
}
bool Database::commit(const QString &connectionName)

View File

@ -71,6 +71,11 @@ DataManager::DataManager()
// Check for "new" entries
if (SettingsManager::self()->autoQueue()) {
// start an immediate transaction since this non-blocking read query
// can change into a blocking write query if the entry needs to be
// queued; this can create a deadlock with other concurrent write
// operations
Database::instance().transaction();
query.prepare(QStringLiteral("SELECT id FROM Entries WHERE feed=:feed AND new=:new ORDER BY updated ASC;"));
query.bindValue(QStringLiteral(":feed"), feedurl);
query.bindValue(QStringLiteral(":new"), true);
@ -85,6 +90,7 @@ DataManager::DataManager()
}
}
}
Database::instance().commit();
}
Q_EMIT feedEntriesUpdated(feedurl);