Конференция "Базы" » Зависает программа после обрыва сетевого соединения с БД [D7, MySQL]
 
  • dmadma (14.10.13 00:20) [0]
    Здравствуйте!

    Попробуйте провести какой эксперимент.
    Создайте новое приложение, новая форма.
    Установите подключение к какой либо базе данных (например ADOConnection)
    База должна находится удаленно, на соседней машине или на хостинге.
    В свойствах в design-time устанавливаем connection:=true - всё ок
    Ставим на форму кнопку и таймер.
    В таймере выставляем 10 секунд и в обработчике пишем команду halt;
    Таймер по умолчанию отключен.
    По нажатии на кнопку пишем:
    включить таймер, далее сделать любой запрос из базы данных и показать результат на форме.
    Всё - этого достаточно для эксперимента.

    Запускаем программу (соединение уже установлено). Нажимаем на кнопочку. Раз - появляются результаты запроса и через 10 сек - прога вылетает. Всё отлично.

    Теперь вторая попытка, но с небольшим но...

    Запускам программу. Теперь вытаскиваем штекер из сетевой карты. Нажимаем на кнопочку. И ВСЁ.... ВИСИМ... Где таймер??? Почему не закрывается программа...

    Я понимаю, что соединение прервалось и могут быть какие-то там из-за этого заморочки, но почему таймер не срабатывает? Ведь мы его запустили до того, как начали делать запрос? Почему ВСЁ висит... Причем висит не по какому-то таймауту, а бесконечно...

    Пробовал с разными базами, пробовал под Win и под Lin - всё одно...
    Что делать? Может кто-то подскажет чего я не понимаю?
  • RWolf © (14.10.13 01:04) [1]
    предположу, что управление не покидает обработчик нажатия, останавливаясь на сделать любой запрос из базы данных.
    потому и не закрывается.
    отчего не генерируется исключение по ошибке связи — это отдельный вопрос.
  • dmadma (14.10.13 02:03) [2]
    Так в том то и дело - нет исключения... Попробуйте сами...
  • sniknik © (14.10.13 08:10) [3]
    > Попробуйте сами...
    100500 раз пробовали уже.

    если в драйвере стоит бесконечное ожидание то никогда не выйдет из зависания... при синхронной модели ты зависишь от того чтобы использованные методы возвращали управление. а т.к. у тебя обработчик блокирован (основной поток), то и таймер не работает, не дожидается события, ди и выполнятся ему негде, его обработчик тоже в основном потоке отрабатывает.
  • sniknik © (14.10.13 08:24) [4]
    +
    в D5 в самом ADO таймаут работал не правильно, приходилось один модуль из него в программу импортировать (чтоб генофонд не трогать) и делать правки... но в D7 там уже все нормально.

    ++
    > В свойствах в design-time устанавливаем connection:=true - всё ок
    в десигне коннект устанавливать вовсе не ок, так не обработаешь исключение при подсоединении. (это не по теме, т.к. у тебя на запросе, но... для инфы)
  • sniknik © (14.10.13 09:49) [5]
    > Попробуйте сами...
    > 100500 раз пробовали уже.
    100501-й раз, первый при вставленном штекере, второй с выдернутым -

    информикс
    0  Выполнено применительно к 100 записям
    1  EOleException : [Informix][Informix ODBC Driver][Informix]System error occurred in network function

    MSSQL
    2  Выполнено применительно к 100 записям
    3  EOleException : Ошибка подключения

    база/драйвер те, что есть, ставить mysql ради "попробуйте" нафиг.
  • dmadma (14.10.13 13:31) [6]
    Программа работает с БД MySql на соседнем компе через сетевое соединение.
    ОС Ubuntu Linux.

    После соединения, делаю запрос - получаю ответ - всё ОК.

    Попробовал вызвать ошибку:
    соединяюсь с базой - вытаскиваю штекер из сетевухи - делаю запрос - ...
    Далее программа висит около 18 минут и после этого дает исключение sql error lost connection...

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

    Помогите разобраться...
  • Ega23 © (14.10.13 15:15) [7]
    Я в отдельном требе создавал отдельный адо-коннект с таймаутом на 15 секунд и с такой же connectionstring. И время от времени пинговал БД простым запросом, что-то типа 'select 1'. Любое исключение трактовал как обрыв связи, о чём сигнализировал главному потоку.
  • sniknik © (14.10.13 16:21) [8]
    так у него и поток повиснет на 18 мин...
    надо смотреть параметры подключения, проверить в чем нибудь "не авторском"..., + попробовать асинхронный режим (таймаут не должен зависеть от "зависания" драйвера),
  • Ega23 © (14.10.13 16:30) [9]

    > так у него и поток повиснет на 18 мин...

    дык ConnectionTimeout выставлялся явно.
    Хотя что-то припоминаю, были там какие-то проблемы с этим таймаутом.
  • sniknik © (14.10.13 16:37) [10]
    в D5, да были. но в D7 вряд ли..., ни разу не сталкивался. (стоит с последним 2м апдейтом - d7_ent_upd1_1.exe)
  • Ega23 © (14.10.13 16:39) [11]

    > в D5, да были. но в D7 вряд ли


    Я уже не помню, откровенно говоря...
  • sniknik © (14.10.13 16:43) [12]
    +
    кстати, ИМХО это не проблема таймаута... т.к. вот то что в [5] пробовал odbc iformix определил разрыв за 0.025 сек, mssql за 0.120 сек. разные да, но в любом случае время ГОРАЗДО меньше определенного (30 сек) таймаута.
  • Медвешонок Порошок (14.10.13 18:53) [13]
    дык ConnectionTimeout выставлялся явно.

    коннект у него успешно все законнектил.
    затем он выдернул шнурок и стал выполнять запрос.
    и его ConnectionTimeout уже ни к селу ни к городу.
  • dmadma (14.10.13 19:56) [14]
    >> коннект у него успешно все законнектил.
    >> затем он выдернул шнурок и стал выполнять запрос.
    >> и его ConnectionTimeout уже ни к селу ни к городу.

    да, всё правильно. выдергиваем шнурок уже после состоявшегося соединения и посылаем запрос - вот тогда висим 18 минут и срабатывает исключение. Если сначала выдернуть, а потом соединяться, то исключение срабатывает мгновенно - тут проблемы нет. Но почему именно через 18 минут и каким образом это поменять непонятно. Стучу бубном уже вторые сутки - и ноль... везде ноль...

    Кто-то отправляет менять настройки (переменные) на MySql-сервере, таймауты разные. Но причем здесь сервер. Он даже не получает запрос. Менял все возможные таймауты и всё равно 18 минут. Менял keep_alive в настройках ОС и всё равно 18 минут, а если быть точнее 17 минут и 45 секунд.

    Я понимаю, что можно засунуть в поток и пинговать, но позвольте. У меня крупный проект, куча различных соединений и если я всё это буду рассовывать по потокам и пытаться синхронизировать, то к 2100 году не доделаю. Мне кажется по правильному, процедура (метод) запуска запроса (пусть это будет .Open или .ExecSQL или .Active:=true) должна сразу выдвать исключение после обнаружения дисконнекта с сервером (пусть хоть с локальным или через сеть). В этом случае реконнектимся и едем дальше без проблем. А потоки в этом случае - это "пытаться запустить в космос велосипед с квадратными колесами".
  • Медвешонок Порошок (14.10.13 20:03) [15]
    Ты когда выдернул сетевой шнурок, сразу выдерни шнур монитора и шнур блока питания компа.
    Тогда никакого зависона видно не будет.
    Проверено, работает.
  • dmadma (14.10.13 20:29) [16]

    > Ты когда выдернул сетевой шнурок, сразу выдерни шнур монитора
    > и шнур блока питания компа.
    > Тогда никакого зависона видно не будет.
    > Проверено, работает.


    можно только питание дергать - остальное само отвалится...

    а если без шуток, то я не понимаю как все работают, ведь обрывы связи это не редкость... где этот таймаут, который выставлен на 18 минут и для какой цели это сделано???
  • sniknik © (14.10.13 22:08) [17]
    > Менял все возможные таймауты и всё равно 18 минут.
    да ты "гониш". (это про "все возможные", не 18 мин, пусть и примерно)

    > а если без шуток, то я не понимаю как все работают, ведь обрывы связи это не редкость...
    без шуток все прекрасно работает, как выше было по твоему "сами попробуйте", попробовано.

    > где этот таймаут, который выставлен на 18 минут и для какой цели это сделано???
    перечисли "все" (раз уж менял "все возможные") там может и найдется...
    цели нет, как нет и такого таймаута.
  • Ega23 © (15.10.13 10:27) [18]

    > коннект у него успешно все законнектил.
    > затем он выдернул шнурок и стал выполнять запрос.


    А в параллельном потоке "создал коннект - убил коннект" дёргается. Тут-то он эту байду и отловит.

    А почему именно 18 минут?
  • dmadma (15.10.13 20:15) [19]
    По поводу висящего запроса к базе данных MySql я выяснил, что сам по себе запрос отправляет данные и ждет ответа, при этом он не проверяет само соединение. Поэтому нужно проверять такие вещи отдельно. Для этого создается отдельный поток и в нем через интервал (10-60 сек) проверяется open-close через дополнительное соединение к этой же базе. Как только выскакивает исключение - значить соединение разорвано и нужно закрыть все другие соединения к базе.

    Ega23 прав...

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

    Спасибо за помощь...
 
Конференция "Базы" » Зависает программа после обрыва сетевого соединения с БД [D7, MySQL]
Есть новые Нет новых   [134428   +39][b:0][p:0.001]