crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Правильное закрытие QSqlQuery
512es
  опции профиля:
сообщение 2.12.2010, 13:30
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 135
Регистрация: 31.10.2008
Пользователь №: 407

Спасибо сказали: 5 раз(а)




Репутация:   0  


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
Сообщение #2


Жаждущий знаний
***

Группа: Участник
Сообщений: 254
Регистрация: 1.1.2009
Из: Санкт-Петербург
Пользователь №: 474

Спасибо сказали: 32 раз(а)




Репутация:   3  


Не надо, QSqlQuery будет разрушен при выходе из зоны видимости.


Сообщение отредактировал panter_dsd - 2.12.2010, 13:36
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 2.12.2010, 13:54
Сообщение #3


фрилансер
******

Группа: Участник
Сообщений: 2935
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(512es @ 2.12.2010, 15:30) *
зависает..

а что именно происходит - просто ступор или окошко какое выпрыгивает ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
xls
  опции профиля:
сообщение 2.12.2010, 15:06
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 44
Регистрация: 6.9.2010
Пользователь №: 2013

Спасибо сказали: 7 раз(а)




Репутация:   2  


Цитата
while (q.next()) { // что будет если по каким либо причинам соединение с базой будет разорвано в момент получения строки?

А вот это интересный вопрос.
Если разрыв соединения будет корректный, т.е. сервер СУБД остановлен, то все будет хорошо - данных не будет вообще.
Если же сервер стоит на другом узле и вы выдерните кабель сетевого соединения, то получите зависание запроса длительностью в тайм-аут соединения с сервером СУБД. И если запрос происходит в основном потоке процесса, то и общее зависание.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
512es
  опции профиля:
сообщение 2.12.2010, 15:41
Сообщение #5


Участник
**

Группа: Участник
Сообщений: 135
Регистрация: 31.10.2008
Пользователь №: 407

Спасибо сказали: 5 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 2.12.2010, 13:54) *
а что именно происходит - просто ступор или окошко какое выпрыгивает ?

Функция запускается в дочернем процессе, и соединение создано тоже в дочернем.
А зависают оба процесса.

Хм.. Может потому что есть ещё одно соединение с локальной БД, использующее подключение созданное в главном потоке, а запрос выполняется в дочернем и по какой то причине не закрывается..


Цитата(xls @ 2.12.2010, 15:06) *
Если разрыв соединения будет корректный, т.е. сервер СУБД остановлен, то все будет хорошо - данных не будет вообще.
Если же сервер стоит на другом узле и вы выдерните кабель сетевого соединения...

Ну.. На практике чаще всего бывает второй вариант. Вы будете в шоке, но соединение происходит через gprs и прочие похожие недоинтернеты =)

Сообщение отредактировал 512es - 2.12.2010, 15:42
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
xls
  опции профиля:
сообщение 6.12.2010, 13:31
Сообщение #6


Студент
*

Группа: Участник
Сообщений: 44
Регистрация: 6.9.2010
Пользователь №: 2013

Спасибо сказали: 7 раз(а)




Репутация:   2  


Цитата
Функция запускается в дочернем процессе, и соединение создано тоже в дочернем.
А зависают оба процесса.

Суда по тому, как Вы создаете запрос, Вы используете "соединение по умолчанию" и в главном и в дочернем потоке, поэтому при зависании соединения с СУБД в дочернем потоке первое же обращение к данным из того же соединения в главном потоке будет аналогичное зависание.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 6.12.2010, 20:53
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(512es @ 2.12.2010, 17:41) *
Функция запускается в дочернем процессе, и соединение создано тоже в дочернем.
вот это учли?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
512es
  опции профиля:
сообщение 6.12.2010, 21:17
Сообщение #8


Участник
**

Группа: Участник
Сообщений: 135
Регистрация: 31.10.2008
Пользователь №: 407

Спасибо сказали: 5 раз(а)




Репутация:   0  


Цитата(Litkevich Yuriy @ 6.12.2010, 20:53) *
вот это учли?


http://www.forum.crossplatform.ru/index.ph...ost&p=43544

читал, но не учёл. со склайтом работает.. склайт собран с флагом threads хотя наверное это и не правильно, но работает же!..

Цитата(xls @ 6.12.2010, 13:31) *
Цитата
Функция запускается в дочернем процессе, и соединение создано тоже в дочернем.
А зависают оба процесса.

Суда по тому, как Вы создаете запрос, Вы используете "соединение по умолчанию" и в главном и в дочернем потоке, поэтому при зависании соединения...


я наверное вас запутал уже. вообщем, вот так всё устроено:

* главный поток
1) склайт соединение с локальной базой

* дочерний поток
1) то же соединение что в первом потоке, используется совместно.
2) соединение с базой постгреса через медленный инет. используется только в этом потоке. частенько разрывы.

отсюда логично предположить что при разрыве связи зависнет дочерний поток, а главный продолжит работать. но почему то этого не происходит..

может и правда это каким то образом связано с тем, что я шарю одно соединение склайта на 2 потока. но блин, ведь тестировал и много тестировал...

может передавать сигналами данные из дочернего в главный, чтобы записать их в базу? или открыть ещё одно подключение, и при ошибке о том что база занята как то повторять запрос..

или всётаки это из за неправильного закрытия запросов?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 6.12.2010, 21:56
Сообщение #9


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(512es @ 6.12.2010, 23:17) *
но почему то этого не происходит..
дык, тыж соединение главного потока пользуешь, вот главный и занят. Доку прочитал, а делаешь поперёк.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
512es
  опции профиля:
сообщение 7.12.2010, 9:17
Сообщение #10


Участник
**

Группа: Участник
Сообщений: 135
Регистрация: 31.10.2008
Пользователь №: 407

Спасибо сказали: 5 раз(а)




Репутация:   0  


Цитата(Litkevich Yuriy @ 6.12.2010, 21:56) *
дык, тыж соединение главного потока пользуешь, вот главный и занят.

В дочернем потоке запросы срабатывают лишь иногда и не блокируют главный поток надолго.

Вот в том то и вопрос:
Как правильно закрывать запросы, чтоб не возникло ситуации когда главный поток подвисает навсегда?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 2.2.2023, 20:47