Конференция "Базы" » ADO Exception на потерю соединения [D7]
 
  • Ega23 © (04.05.08 13:20) [0]
    есть ли какое-то общее исключение?
    Допустим, я выполняю некий запрос (Select, Insert, Update, Delete - не суть). Обкладываю выполнение try ... except
    Есть ли какое-то общее исключение, что не ошибка в синтаксисе запроса, а именно разорвалось соединение?

    СУБД - разные, должно работать как минимум с Postgres, MSSQL и Oracle.
  • Anatoly Podgoretsky © (04.05.08 13:41) [1]
    А компоненты соединения тоже разные?
  • Anatoly Podgoretsky © (04.05.08 13:44) [2]
    Application.OnExeption
  • Ega23 © (04.05.08 13:47) [3]

    > А компоненты соединения тоже разные?


    Нет, везде ADO.


    > Application.OnExeption


    Не катит, нет Application... :(
  • Anatoly Podgoretsky © (04.05.08 13:54) [4]
    А нам что догадываться, что у тебя есть, чего нет?
    Могу посоветовать только создать наследников от твоих компонент с новым обработчиком OnAbnormalDisconnect
    А что плохого в локальной обработке try except она же более гибкая?
    Можешь передавать исключение куда угодно на индивидуальной основе.
  • Ega23 © (04.05.08 14:00) [5]

    > А что плохого в локальной обработке try except она же более
    > гибкая?


    Дык ничего плохого в ней, я же как раз за неё и спрашиваю.
    Интересует как отличить ошибку SQL-запроса (например, такой таблицы не существует, или "key violation" какой-нибудь) от "Connection lost"?
    Короче, есть у ADO такой код исключения, или нет?

    Смысл в том, что на ошибку синтаксиса просто должно выругаться с отписью в лог, а вот на потерю соединения - выругаться, отписаться в лог и запустить процедуру reconnect-а (с каким-то количеством попыток).
  • Ega23 © (04.05.08 14:00) [6]

    > OnAbnormalDisconnect


    Сейчас почитаю...
  • Ega23 © (04.05.08 15:22) [7]
    Короче, провел имитацию разрыва соединения с MSSQL и с Postgres.
    приходит EOleSysError c ErrorCode=-2147467259 (я так понимаю, что это равнозначно 0x80004005) Только что-то в MSDN никак описание этого дела найти не могу... :(
  • Anatoly Podgoretsky © (04.05.08 16:03) [8]
    > Ega23  (04.05.2008 15:22:07)  [7]

    Ну вот и определил, как их отличать.
    А в except можешь вызвать что угодно и делать дальше тоже что угодно, хоть снова возбуждать исключение, только для нужных типов.
  • Anatoly Podgoretsky © (04.05.08 16:13) [9]
    > Ega23  (04.05.2008 15:22:07)  [7]

    Это хитрая ошибка, информации по ней много, в общем означает, что куда то нельзя достучаться, обычно подробности в расшифровке в текстовом сообщении.
    Например Disk or Network Error
    А что еще можно решить, если нет доступа до ресурса.
  • Ega23 © (04.05.08 16:21) [10]

    > Ну вот и определил, как их отличать.


    Поигрался дальше, всё далеко не так просто.
    Короче, как MSDN говорит, 0x80004005 - это E_FAIL для COM.
    В случае ADO-подключения к MSSQL, опытным путём установил, что данное EOleSysError поднимается при потере соединения.
    С другой стороны, в случае ADO-подключения к Postgres, исключение с данным кодом поднимается и при потере соединения, и при ошибке SQL (например, обращение к несуществующему объекту).
    Вся разница - в текстовой информации. Подозреваю, что данное дело берётся откуда-то из ресурсов (вот только на уровне delphi или OLEDB-provider - непонятно).

    Пока вижу такой вариант действий: ловим любое исключение от DB-сервера. Внутри except-блока пытаемся установить второе соединение к серверу. При исключении второго соединения - запускаем процедуру реконнекта. Иначе - считаем, что это было просто исключение на уровне SQL.

    Есть второй вариант: тупо вешаем таймер, который раз в N секунд стреляет пинг в базу, что-то типа Select @@version. И его уже в try...except ловим. Как только Except - создаём event Disconnected. Иначе - Connected.

    Какой вариант лучше?

    Насколько такой вариант правильный?
  • Ega23 © (04.05.08 16:23) [11]
    Да, третий вариант - анализ текстового сообщения Exception. Но тут вопрос - с чем его сравнивать?
  • Anatoly Podgoretsky © (04.05.08 16:35) [12]
    Сложные ты вопросы задаешь "Что лучше".
    По третьему варианту - ни с чем не сравнивать, поскольку это не стабильно даже в рамках одной версии. Текстовая часть не для анализа, а для выдачи пользователю.
    Можешь рискнуть, сравнивать со своей константой, но я бы не рискнул.

    E_FAIL это и есть точное название ошибки - не возможность подключения/работы с ресурсов. Вот только различить не возможно, дисконнект это или другая ошибка доступа.
    И по поводу "EOleSysError поднимается при потере соединения." - это не так, при потери соединения никаких ошибок не возникает, эта ошибка возникает при попытке работы с ресурсом, после того как соединение потеряно, или ресурс просто недоступен.

    Select @@version решение верное для определения недоступности сервера и/или ее БД. Тем более, что у тебя в этом случае не возникает неодназначности с MySQL или любой другой базы. Select @@version можно заменить, чем ни будь другим аналогичным, например Select 1 - не везде работает.
  • Anatoly Podgoretsky © (04.05.08 16:35) [13]

    > (вот только на уровне delphi или OLEDB-provider - непонятно).

    Из провайдера или даже СУБД
  • Ega23 © (04.05.08 16:40) [14]

    > И по поводу "EOleSysError поднимается при потере соединения.
    > " - это не так, при потери соединения никаких ошибок не
    > возникает, эта ошибка возникает при попытке работы с ресурсом,
    >  после того как соединение потеряно, или ресурс просто недоступен.


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


    > Select @@version решение верное для определения недоступности
    > сервера и/или ее БД. Тем более, что у тебя в этом случае
    > не возникает неодназначности с MySQL или любой другой базы.
    >  Select @@version можно заменить, чем ни будь другим аналогичным,
    >  например Select 1 - не везде работает.


    Ну это понятно, Select @@version я как пример "лёгкого" запроса привёл.
  • Anatoly Podgoretsky © (04.05.08 17:44) [15]
    > Ega23  (04.05.2008 16:40:14)  [14]

    А попроще, сервер работает, но "остановлена" база, кстати Select @@version вероятнее всего отработает без ошибки. Поэтому если хочешь использовать подобный подход, то надо обращаться к какой ни будь таблице именно базы данных, и что бы не привязываться к системным таблицам, что тоже неверно, обращаться надо к пользовательским. Запрос может быть невыполнимим WHERE 1 <> 1
  • Ega23 © (04.05.08 18:01) [16]

    > если хочешь использовать подобный подход, то надо обращаться
    > к какой ни будь таблице именно базы данных, и что бы не
    > привязываться к системным таблицам, что тоже неверно, обращаться
    > надо к пользовательским


    Это понятно, у меня под всеми СУБД будет своя таблица GlobalVars, где версия ДБ хранится (ну и прочая фигня). К ней и будет пинг.
  • Anatoly Podgoretsky © (04.05.08 18:38) [17]
    > Ega23  (04.05.2008 18:01:16)  [16]

    Ну так ты все уже решил, только внешнего одобрения ожидаешь.
  • piople © (08.05.08 05:51) [18]
      try
      ...
      ADOQuery.Close;
      ADOQuery.SQL.Clear;
      ADOQuery.SQL.Add('SELECT TOP 10 GuID, ShortMess, LongMess, TDate FROM SiteDBNews ORDER BY TDate DESC');
      ADOQuery.Open;
      ...    

      except
         on E: Exception do
         begin
            Response.Content := 'Error - ' + E.Message;
            exit;
         end;
      end;



    По идеи хотя хз
  • Ega23 © (08.05.08 10:02) [19]

    > piople ©   (08.05.08 05:51) [18]


    Это ты к чему сиё убожество написал?
 
Конференция "Базы" » ADO Exception на потерю соединения [D7]
Есть новые Нет новых   [134432   +19][b:0][p:0.001]