Автор: 512es 2.12.2010, 13:30
bool stop = false;
int function()
{
if (stop) return 1;
QSqlQuery q;
q.prepare("SELECT * FROM table WHERE id = ?;");
q.addBindValue(5);
if (!q.exec()) return 2; // ну, тут понятно.. ничего не остаётся больше кроме как писать ошибку и выходить из функции. q поидее удалится и ничего лишнего в памяти не останется
while (q.next()) { // что будет если по каким либо причинам соединение с базой будет разорвано в момент получения строки?
if (stop) {
// надо ли делать тут q.clear() ???
// поидее мы не все ещё выбрали строки запроса
// или же, выйдя из function(), q удалится и закроет запрос сам?
return 3;
}
}
return 0;
}
void runFunction()
{
function();
}
Переменная stop служит для прерывания выполнения цикла, например при закрытии программы.
Остаётся ли какой нибудь мусор в памяти при выходе из функции? Ведь соединение с базой остаётся открытым.
Иногда основной поток программы зависает.. Не пойму, в чём дело
Автор: panter_dsd 2.12.2010, 13:35
Не надо, QSqlQuery будет разрушен при выходе из зоны видимости.
Автор: Алексей1153 2.12.2010, 13:54
Цитата(512es @ 2.12.2010, 15:30)
зависает..
а что именно происходит - просто ступор или окошко какое выпрыгивает ?
Автор: xls 2.12.2010, 15:06
Цитата
while (q.next()) { // что будет если по каким либо причинам соединение с базой будет разорвано в момент получения строки?
А вот это интересный вопрос.
Если разрыв соединения будет корректный, т.е. сервер СУБД остановлен, то все будет хорошо - данных не будет вообще.
Если же сервер стоит на другом узле и вы выдерните кабель сетевого соединения, то получите зависание запроса длительностью в тайм-аут соединения с сервером СУБД. И если запрос происходит в основном потоке процесса, то и общее зависание.
Автор: 512es 2.12.2010, 15:41
Цитата(Алексей1153 @ 2.12.2010, 13:54)
а что именно происходит - просто ступор или окошко какое выпрыгивает ?
Функция запускается в дочернем процессе, и соединение создано тоже в дочернем.
А зависают оба процесса.
Хм.. Может потому что есть ещё одно соединение с локальной БД, использующее подключение созданное в главном потоке, а запрос выполняется в дочернем и по какой то причине не закрывается..
Цитата(xls @ 2.12.2010, 15:06)
Если разрыв соединения будет корректный, т.е. сервер СУБД остановлен, то все будет хорошо - данных не будет вообще.
Если же сервер стоит на другом узле и вы выдерните кабель сетевого соединения...
Ну.. На практике чаще всего бывает второй вариант. Вы будете в шоке, но соединение происходит через gprs и прочие похожие недоинтернеты =)
Автор: xls 6.12.2010, 13:31
Цитата
Функция запускается в дочернем процессе, и соединение создано тоже в дочернем.
А зависают оба процесса.
Суда по тому, как Вы создаете запрос, Вы используете "соединение по умолчанию" и в главном и в дочернем потоке, поэтому при зависании соединения с СУБД в дочернем потоке первое же обращение к данным из того же соединения в главном потоке будет аналогичное зависание.
Автор: Litkevich Yuriy 6.12.2010, 20:53
Цитата(512es @ 2.12.2010, 17:41)
Функция запускается в дочернем процессе, и соединение создано тоже в дочернем.
вот http://doc.crossplatform.ru/qt/4.4.3/threads.html#threads-and-the-sql-module учли?
Автор: 512es 6.12.2010, 21:17
Цитата(Litkevich Yuriy @ 6.12.2010, 20:53)
вот http://doc.crossplatform.ru/qt/4.4.3/threads.html#threads-and-the-sql-module учли?
http://www.forum.crossplatform.ru/index.php?showtopic=5092&view=findpost&p=43544
читал, но не учёл. со склайтом работает.. склайт собран с флагом threads хотя наверное это и не правильно, но работает же!..
Цитата(xls @ 6.12.2010, 13:31)
Цитата
Функция запускается в дочернем процессе, и соединение создано тоже в дочернем.
А зависают оба процесса.
Суда по тому, как Вы создаете запрос, Вы используете "соединение по умолчанию" и в главном и в дочернем потоке, поэтому при зависании соединения...
я наверное вас запутал уже. вообщем, вот так всё устроено:
* главный поток
1) склайт соединение с локальной базой
* дочерний поток
1) то же соединение что в первом потоке, используется совместно.
2) соединение с базой постгреса через медленный инет. используется только в этом потоке. частенько разрывы.
отсюда логично предположить что при разрыве связи зависнет дочерний поток, а главный продолжит работать. но почему то этого не происходит..
может и правда это каким то образом связано с тем, что я шарю одно соединение склайта на 2 потока. но блин, ведь тестировал и много тестировал...
может передавать сигналами данные из дочернего в главный, чтобы записать их в базу? или открыть ещё одно подключение, и при ошибке о том что база занята как то повторять запрос..
или всётаки это из за неправильного закрытия запросов?
Автор: Litkevich Yuriy 6.12.2010, 21:56
Цитата(512es @ 6.12.2010, 23:17)
но почему то этого не происходит..
дык, тыж соединение главного потока пользуешь, вот главный и занят. Доку прочитал, а делаешь поперёк.
Автор: 512es 7.12.2010, 9:17
Цитата(Litkevich Yuriy @ 6.12.2010, 21:56)
дык, тыж соединение главного потока пользуешь, вот главный и занят.
В дочернем потоке запросы срабатывают лишь иногда и не блокируют главный поток надолго.
Вот в том то и вопрос:
Как правильно закрывать запросы, чтоб не возникло ситуации когда главный поток подвисает навсегда?