-
есть ли какое-то общее исключение? Допустим, я выполняю некий запрос (Select, Insert, Update, Delete - не суть). Обкладываю выполнение try ... except Есть ли какое-то общее исключение, что не ошибка в синтаксисе запроса, а именно разорвалось соединение?
СУБД - разные, должно работать как минимум с Postgres, MSSQL и Oracle.
-
А компоненты соединения тоже разные?
-
Application.OnExeption
-
> А компоненты соединения тоже разные?
Нет, везде ADO.
> Application.OnExeption
Не катит, нет Application... :(
-
А нам что догадываться, что у тебя есть, чего нет? Могу посоветовать только создать наследников от твоих компонент с новым обработчиком OnAbnormalDisconnect А что плохого в локальной обработке try except она же более гибкая? Можешь передавать исключение куда угодно на индивидуальной основе.
-
> А что плохого в локальной обработке try except она же более > гибкая?
Дык ничего плохого в ней, я же как раз за неё и спрашиваю. Интересует как отличить ошибку SQL-запроса (например, такой таблицы не существует, или "key violation" какой-нибудь) от "Connection lost"? Короче, есть у ADO такой код исключения, или нет?
Смысл в том, что на ошибку синтаксиса просто должно выругаться с отписью в лог, а вот на потерю соединения - выругаться, отписаться в лог и запустить процедуру reconnect-а (с каким-то количеством попыток).
-
> OnAbnormalDisconnect
Сейчас почитаю...
-
Короче, провел имитацию разрыва соединения с MSSQL и с Postgres. приходит EOleSysError c ErrorCode=-2147467259 (я так понимаю, что это равнозначно 0x80004005) Только что-то в MSDN никак описание этого дела найти не могу... :(
-
> Ega23 (04.05.2008 15:22:07) [7]
Ну вот и определил, как их отличать. А в except можешь вызвать что угодно и делать дальше тоже что угодно, хоть снова возбуждать исключение, только для нужных типов.
-
> Ega23 (04.05.2008 15:22:07) [7]
Это хитрая ошибка, информации по ней много, в общем означает, что куда то нельзя достучаться, обычно подробности в расшифровке в текстовом сообщении. Например Disk or Network Error А что еще можно решить, если нет доступа до ресурса.
-
> Ну вот и определил, как их отличать.
Поигрался дальше, всё далеко не так просто. Короче, как 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.
Какой вариант лучше?
Насколько такой вариант правильный?
-
Да, третий вариант - анализ текстового сообщения Exception. Но тут вопрос - с чем его сравнивать?
-
Сложные ты вопросы задаешь "Что лучше". По третьему варианту - ни с чем не сравнивать, поскольку это не стабильно даже в рамках одной версии. Текстовая часть не для анализа, а для выдачи пользователю. Можешь рискнуть, сравнивать со своей константой, но я бы не рискнул.
E_FAIL это и есть точное название ошибки - не возможность подключения/работы с ресурсов. Вот только различить не возможно, дисконнект это или другая ошибка доступа. И по поводу "EOleSysError поднимается при потере соединения." - это не так, при потери соединения никаких ошибок не возникает, эта ошибка возникает при попытке работы с ресурсом, после того как соединение потеряно, или ресурс просто недоступен.
Select @@version решение верное для определения недоступности сервера и/или ее БД. Тем более, что у тебя в этом случае не возникает неодназначности с MySQL или любой другой базы. Select @@version можно заменить, чем ни будь другим аналогичным, например Select 1 - не везде работает.
-
> (вот только на уровне delphi или OLEDB-provider - непонятно).
Из провайдера или даже СУБД
-
> И по поводу "EOleSysError поднимается при потере соединения. > " - это не так, при потери соединения никаких ошибок не > возникает, эта ошибка возникает при попытке работы с ресурсом, > после того как соединение потеряно, или ресурс просто недоступен.
Ну я имел ввиду, что я останавливаю сервер, после чего пытаюсь выполнить к нему запрос. Естественно исключение поднимается не в момент остановки, а при попытки выполнения SQL на остановленном сервере.
> Select @@version решение верное для определения недоступности > сервера и/или ее БД. Тем более, что у тебя в этом случае > не возникает неодназначности с MySQL или любой другой базы. > Select @@version можно заменить, чем ни будь другим аналогичным, > например Select 1 - не везде работает.
Ну это понятно, Select @@version я как пример "лёгкого" запроса привёл.
-
> Ega23 (04.05.2008 16:40:14) [14]
А попроще, сервер работает, но "остановлена" база, кстати Select @@version вероятнее всего отработает без ошибки. Поэтому если хочешь использовать подобный подход, то надо обращаться к какой ни будь таблице именно базы данных, и что бы не привязываться к системным таблицам, что тоже неверно, обращаться надо к пользовательским. Запрос может быть невыполнимим WHERE 1 <> 1
-
> если хочешь использовать подобный подход, то надо обращаться > к какой ни будь таблице именно базы данных, и что бы не > привязываться к системным таблицам, что тоже неверно, обращаться > надо к пользовательским
Это понятно, у меня под всеми СУБД будет своя таблица GlobalVars, где версия ДБ хранится (ну и прочая фигня). К ней и будет пинг.
-
> Ega23 (04.05.2008 18:01:16) [16]
Ну так ты все уже решил, только внешнего одобрения ожидаешь.
-
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; По идеи хотя хз
-
> piople © (08.05.08 05:51) [18]
Это ты к чему сиё убожество написал?
|