Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.11.23;
Скачать: CL | DM;

Вниз

ADO Exception на потерю соединения   Найти похожие ветки 

 
Ega23 ©   (2008-05-04 13:20) [0]

есть ли какое-то общее исключение?
Допустим, я выполняю некий запрос (Select, Insert, Update, Delete - не суть). Обкладываю выполнение try ... except
Есть ли какое-то общее исключение, что не ошибка в синтаксисе запроса, а именно разорвалось соединение?

СУБД - разные, должно работать как минимум с Postgres, MSSQL и Oracle.


 
Anatoly Podgoretsky ©   (2008-05-04 13:41) [1]

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


 
Anatoly Podgoretsky ©   (2008-05-04 13:44) [2]

Application.OnExeption


 
Ega23 ©   (2008-05-04 13:47) [3]


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


Нет, везде ADO.


> Application.OnExeption


Не катит, нет Application... :(


 
Anatoly Podgoretsky ©   (2008-05-04 13:54) [4]

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


 
Ega23 ©   (2008-05-04 14:00) [5]


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


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

Смысл в том, что на ошибку синтаксиса просто должно выругаться с отписью в лог, а вот на потерю соединения - выругаться, отписаться в лог и запустить процедуру reconnect-а (с каким-то количеством попыток).


 
Ega23 ©   (2008-05-04 14:00) [6]


> OnAbnormalDisconnect


Сейчас почитаю...


 
Ega23 ©   (2008-05-04 15:22) [7]

Короче, провел имитацию разрыва соединения с MSSQL и с Postgres.
приходит EOleSysError c ErrorCode=-2147467259 (я так понимаю, что это равнозначно 0x80004005) Только что-то в MSDN никак описание этого дела найти не могу... :(


 
Anatoly Podgoretsky ©   (2008-05-04 16:03) [8]

> Ega23  (04.05.2008 15:22:07)  [7]

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


 
Anatoly Podgoretsky ©   (2008-05-04 16:13) [9]

> Ega23  (04.05.2008 15:22:07)  [7]

Это хитрая ошибка, информации по ней много, в общем означает, что куда то нельзя достучаться, обычно подробности в расшифровке в текстовом сообщении.
Например Disk or Network Error
А что еще можно решить, если нет доступа до ресурса.


 
Ega23 ©   (2008-05-04 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 ©   (2008-05-04 16:23) [11]

Да, третий вариант - анализ текстового сообщения Exception. Но тут вопрос - с чем его сравнивать?


 
Anatoly Podgoretsky ©   (2008-05-04 16:35) [12]

Сложные ты вопросы задаешь "Что лучше".
По третьему варианту - ни с чем не сравнивать, поскольку это не стабильно даже в рамках одной версии. Текстовая часть не для анализа, а для выдачи пользователю.
Можешь рискнуть, сравнивать со своей константой, но я бы не рискнул.

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

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


 
Anatoly Podgoretsky ©   (2008-05-04 16:35) [13]


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

Из провайдера или даже СУБД


 
Ega23 ©   (2008-05-04 16:40) [14]


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


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


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


Ну это понятно, Select @@version я как пример "лёгкого" запроса привёл.


 
Anatoly Podgoretsky ©   (2008-05-04 17:44) [15]

> Ega23  (04.05.2008 16:40:14)  [14]

А попроще, сервер работает, но "остановлена" база, кстати Select @@version вероятнее всего отработает без ошибки. Поэтому если хочешь использовать подобный подход, то надо обращаться к какой ни будь таблице именно базы данных, и что бы не привязываться к системным таблицам, что тоже неверно, обращаться надо к пользовательским. Запрос может быть невыполнимим WHERE 1 <> 1


 
Ega23 ©   (2008-05-04 18:01) [16]


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


Это понятно, у меня под всеми СУБД будет своя таблица GlobalVars, где версия ДБ хранится (ну и прочая фигня). К ней и будет пинг.


 
Anatoly Podgoretsky ©   (2008-05-04 18:38) [17]

> Ega23  (04.05.2008 18:01:16)  [16]

Ну так ты все уже решил, только внешнего одобрения ожидаешь.


 
piople ©   (2008-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 ©   (2008-05-08 10:02) [19]


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


Это ты к чему сиё убожество написал?



Страницы: 1 вся ветка

Текущий архив: 2008.11.23;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.013 c
15-1222066417
Slider007
2008-09-22 10:53
2008.11.23
С днем рождения ! 22 сентября 2008 понедельник


2-1223710893
deras
2008-10-11 11:41
2008.11.23
Как синхронизировать одну таблицу двух разных БД?


15-1222011631
SergP
2008-09-21 19:40
2008.11.23
Oracle. Listener


2-1223853210
ply
2008-10-13 03:13
2008.11.23
работа с архивами


4-1200314598
toboom
2008-01-14 15:43
2008.11.23
Расшаривание папок в Win XP