-
Здравствуйте!
Попробуйте провести какой эксперимент.
Создайте новое приложение, новая форма.
Установите подключение к какой либо базе данных (например ADOConnection)
База должна находится удаленно, на соседней машине или на хостинге.
В свойствах в design-time устанавливаем connection:=true - всё ок
Ставим на форму кнопку и таймер.
В таймере выставляем 10 секунд и в обработчике пишем команду halt;
Таймер по умолчанию отключен.
По нажатии на кнопку пишем:
включить таймер, далее сделать любой запрос из базы данных и показать результат на форме.
Всё - этого достаточно для эксперимента.
Запускаем программу (соединение уже установлено). Нажимаем на кнопочку. Раз - появляются результаты запроса и через 10 сек - прога вылетает. Всё отлично.
Теперь вторая попытка, но с небольшим но...
Запускам программу. Теперь вытаскиваем штекер из сетевой карты. Нажимаем на кнопочку. И ВСЁ.... ВИСИМ... Где таймер??? Почему не закрывается программа...
Я понимаю, что соединение прервалось и могут быть какие-то там из-за этого заморочки, но почему таймер не срабатывает? Ведь мы его запустили до того, как начали делать запрос? Почему ВСЁ висит... Причем висит не по какому-то таймауту, а бесконечно...
Пробовал с разными базами, пробовал под Win и под Lin - всё одно...
Что делать? Может кто-то подскажет чего я не понимаю?
-
предположу, что управление не покидает обработчик нажатия, останавливаясь на сделать любой запрос из базы данных.
потому и не закрывается.
отчего не генерируется исключение по ошибке связи — это отдельный вопрос.
-
Так в том то и дело - нет исключения... Попробуйте сами...
-
> Попробуйте сами...
100500 раз пробовали уже.
если в драйвере стоит бесконечное ожидание то никогда не выйдет из зависания... при синхронной модели ты зависишь от того чтобы использованные методы возвращали управление. а т.к. у тебя обработчик блокирован (основной поток), то и таймер не работает, не дожидается события, ди и выполнятся ему негде, его обработчик тоже в основном потоке отрабатывает.
-
+
в D5 в самом ADO таймаут работал не правильно, приходилось один модуль из него в программу импортировать (чтоб генофонд не трогать) и делать правки... но в D7 там уже все нормально.
++
> В свойствах в design-time устанавливаем connection:=true - всё ок
в десигне коннект устанавливать вовсе не ок, так не обработаешь исключение при подсоединении. (это не по теме, т.к. у тебя на запросе, но... для инфы)
-
> Попробуйте сами...
> 100500 раз пробовали уже.
100501-й раз, первый при вставленном штекере, второй с выдернутым -
информикс
0 Выполнено применительно к 100 записям
1 EOleException : [Informix][Informix ODBC Driver][Informix]System error occurred in network function
MSSQL
2 Выполнено применительно к 100 записям
3 EOleException : Ошибка подключения
база/драйвер те, что есть, ставить mysql ради "попробуйте" нафиг.
-
Программа работает с БД MySql на соседнем компе через сетевое соединение.
ОС Ubuntu Linux.
После соединения, делаю запрос - получаю ответ - всё ОК.
Попробовал вызвать ошибку:
соединяюсь с базой - вытаскиваю штекер из сетевухи - делаю запрос - ...
Далее программа висит около 18 минут и после этого дает исключение sql error lost connection...
Почему так долго и где можно изменить это время до 10 секунд.
Я понимаю, что выставляться это должно на клиенте, так как после разрыва сети сервер недоступен...
Помогите разобраться...
-
Я в отдельном требе создавал отдельный адо-коннект с таймаутом на 15 секунд и с такой же connectionstring. И время от времени пинговал БД простым запросом, что-то типа 'select 1'. Любое исключение трактовал как обрыв связи, о чём сигнализировал главному потоку.
-
так у него и поток повиснет на 18 мин...
надо смотреть параметры подключения, проверить в чем нибудь "не авторском"..., + попробовать асинхронный режим (таймаут не должен зависеть от "зависания" драйвера),
-
> так у него и поток повиснет на 18 мин...
дык ConnectionTimeout выставлялся явно.
Хотя что-то припоминаю, были там какие-то проблемы с этим таймаутом.
-
в D5, да были. но в D7 вряд ли..., ни разу не сталкивался. (стоит с последним 2м апдейтом - d7_ent_upd1_1.exe)
-
> в D5, да были. но в D7 вряд ли
Я уже не помню, откровенно говоря...
-
+
кстати, ИМХО это не проблема таймаута... т.к. вот то что в [5] пробовал odbc iformix определил разрыв за 0.025 сек, mssql за 0.120 сек. разные да, но в любом случае время ГОРАЗДО меньше определенного (30 сек) таймаута.
-
дык ConnectionTimeout выставлялся явно.
коннект у него успешно все законнектил.
затем он выдернул шнурок и стал выполнять запрос.
и его ConnectionTimeout уже ни к селу ни к городу.
-
>> коннект у него успешно все законнектил.
>> затем он выдернул шнурок и стал выполнять запрос.
>> и его ConnectionTimeout уже ни к селу ни к городу.
да, всё правильно. выдергиваем шнурок уже после состоявшегося соединения и посылаем запрос - вот тогда висим 18 минут и срабатывает исключение. Если сначала выдернуть, а потом соединяться, то исключение срабатывает мгновенно - тут проблемы нет. Но почему именно через 18 минут и каким образом это поменять непонятно. Стучу бубном уже вторые сутки - и ноль... везде ноль...
Кто-то отправляет менять настройки (переменные) на MySql-сервере, таймауты разные. Но причем здесь сервер. Он даже не получает запрос. Менял все возможные таймауты и всё равно 18 минут. Менял keep_alive в настройках ОС и всё равно 18 минут, а если быть точнее 17 минут и 45 секунд.
Я понимаю, что можно засунуть в поток и пинговать, но позвольте. У меня крупный проект, куча различных соединений и если я всё это буду рассовывать по потокам и пытаться синхронизировать, то к 2100 году не доделаю. Мне кажется по правильному, процедура (метод) запуска запроса (пусть это будет .Open или .ExecSQL или .Active:=true) должна сразу выдвать исключение после обнаружения дисконнекта с сервером (пусть хоть с локальным или через сеть). В этом случае реконнектимся и едем дальше без проблем. А потоки в этом случае - это "пытаться запустить в космос велосипед с квадратными колесами".
-
Ты когда выдернул сетевой шнурок, сразу выдерни шнур монитора и шнур блока питания компа.
Тогда никакого зависона видно не будет.
Проверено, работает.
-
> Ты когда выдернул сетевой шнурок, сразу выдерни шнур монитора
> и шнур блока питания компа.
> Тогда никакого зависона видно не будет.
> Проверено, работает.
можно только питание дергать - остальное само отвалится...
а если без шуток, то я не понимаю как все работают, ведь обрывы связи это не редкость... где этот таймаут, который выставлен на 18 минут и для какой цели это сделано???
-
> Менял все возможные таймауты и всё равно 18 минут.
да ты "гониш". (это про "все возможные", не 18 мин, пусть и примерно)
> а если без шуток, то я не понимаю как все работают, ведь обрывы связи это не редкость...
без шуток все прекрасно работает, как выше было по твоему "сами попробуйте", попробовано.
> где этот таймаут, который выставлен на 18 минут и для какой цели это сделано???
перечисли "все" (раз уж менял "все возможные") там может и найдется...
цели нет, как нет и такого таймаута.
-
> коннект у него успешно все законнектил.
> затем он выдернул шнурок и стал выполнять запрос.
А в параллельном потоке "создал коннект - убил коннект" дёргается. Тут-то он эту байду и отловит.
А почему именно 18 минут?
-
По поводу висящего запроса к базе данных MySql я выяснил, что сам по себе запрос отправляет данные и ждет ответа, при этом он не проверяет само соединение. Поэтому нужно проверять такие вещи отдельно. Для этого создается отдельный поток и в нем через интервал (10-60 сек) проверяется open-close через дополнительное соединение к этой же базе. Как только выскакивает исключение - значить соединение разорвано и нужно закрыть все другие соединения к базе.
Ega23 прав...
Но мне кажется было бы правильно, если сам запрос просто выдавал бы исключение в случае потери связи и все.
Спасибо за помощь...