На данный момент есть программа, использующая подключение к БД sqlite:
Инициализация:
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(path);
if (!db.open())
{
return false;
}
QSqlQuery query = QSqlQuery(db);
query.prepare("INSERT INTO ip_list (ip, host, vps, assigned) "
"VALUES (?, ?, ?, ?)");
query.addBindValue(new_ip->ip);
query.addBindValue(new_ip->host);
query.addBindValue(new_ip->vps);
query.addBindValue(new_ip->assigned);
query.exec();
Ну, в принципе так делать можно. Просто SQLite может обрабатывать только один запрос на запись одновременно. Если в момент записи произойдет попытка еще одной записи в БД из другого потока, то этот второй поток просто будет заморожен пока первая операция записи не завершится.
Недавно проводил стресс тесты. Методом экспериментов выяснил что работать с одним соединением в двух потоках лучше, чем с двумя отдельными. Хотя в доках по Qt написано что этого делать нельзя..
На деле разница получается в том что, когда одно соединение используется, второй поток блокируется. А если несколько соединений с одним файлом базы то второй поток иногда получает отказ в выполнении запроса.
Постгрес в нескольких потоках вообще начинает страшно глючить, а склайт работает...
А по теме советую всётаки вывести работу с базой в отдельный поток, ака db writer, и присылать в него данные через сигналы и слоты в режиме очереди. Тогда работать будет вообще идеально.
Тем более, если вдруг база не успеет записать данные до получения новых, они просто выстроятся в очередь и запишутся чуть позже, ничего не теряя.
тыкс.. кажется я придумал способ получше. точнее лишь более корректный, чем шарить соединение на 2 потока.
чтобы не получать ошибку о том что бд занята можно указать значение таймаунта побольше.
db.setConnectOptions("QSQLITE_BUSY_TIMEOUT=10000");
правда не факт что подвисший поток всётаки разлочит базу и главный поток запишет данные
Недавно споткнулся о грабли многопоточности и QSQLite. Сначала не обратил внимание на http://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module и использовал одно подключение QSqlDatabase в нескольких потоках. В результате приложение падало с "unhandled exception" то в qsqlite.dll, то в ntdll.dll. Причем могло упасть как через 10 минут стресс-теста, так и через 2 часа.
Проблему решил с помощью http://doc.qt.io/qt-5/qsqldatabase.html#cloneDatabase, выдавая каждому потоку свое подключение к базе. Чтобы избежать ошибки "database is locked" работу с SQL обвернул в http://doc.qt.io/qt-5/qmutex.html.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)