Работа с сервером баз данных
При загрузке данных, этот способ единственный.
Соответственно от туда и выдается сообщение пользователю. Предварительно можно попытаться выполнить реконнект к серверу, а только после этого выдавать сообщение о сбое подключения.
При возникновении ошибки при правке (удалении) записи существуют свои события в которых эта ситуация обрабатывается. Если критично - то необходимо перед выполнением любой операции выполнять реконнект - и перехватывать эксепшион в случае невозможности.
TDataSet *DataSet)
{
try
{
if( Form1->DBGrid2->Fields[1]->Value.IsNull()
|| Form1->DBGrid2->Fields[2]->Value.IsNull())
{
sShowMessage("Поля \"Доступ\" и \"Описание\" должны быть заполнены");
Abort();
}
}
catch(...)
{
sShowMessage("Не удалось отправить в базу данных");
Abort();
}
}
но это не помогает. Если связь прервется то обработчик сработает, но если связь вдруг появиться, то обработчик продолжает выдавать ошибку, не взирая на то что связь с сервером восстоновилась.
скажем дисэйблишь окошко... выдаёшь сплэшскрин... где юзера информируешь о том, что счась происходит, а прога в это время судорожно пытается повторить отправку данных, или реконнект к БД и отправку...
PS: эт на случай если возник exception в данном тобой примере
как бы вот так.... :)
Связь рвётся каждые пять минут, хаотично, а электричество остаётся?
Дело в том, что на в полне развитой форме может быть достаточно много компонентов, соединённых с базой, имеющих определённое содержимое, состояние и т.д. И что это всё запоминать? По-моему лучше наладить сетку. Если это другой вид связи, то и подход для работы должен быть другим. Как в WEB приложениях, каждый раз реконнект.
1)каждое обращение оформляем как :
конект .
действие ,если конект успешен .
дисконект .
2)создаём таймер .
по таймеру проверяем связь (пингуем).
также проверяем связь при попытке совершения транзакций .
если связи нет пытаемся воостановить .
значит стандартное решение в такой ситации это пинг по таймеру.
Получилось примерно так:
{
Screen->Cursor = crDefault;
AnsiString ErrorMessageHint;
// ...
else if(E->Message.SubString(1, 9) == "ORA-01031" ||
E->Message.SubString(1, 9) == "ORA-00942" ||
E->Message.SubString(1, 9) == "ORA-06550")// Privilegies
ErrorMessageHint = "Извините, но у Вас нет прав на данное действие";
else if(E->Message.SubString(1, 9) == "ORA-12535")// Ссылка на самого себя
ErrorMessageHint = "Проблеммы работы данного сервера. \nПроверьте правильность имени сервера и попытайтесь зайти снова. \nЕсли эта ошибка повторится свяжитесь с администратором сервера.";
else if(E->Message.SubString(1, 9)=="ORA-00001")// Ссылка на самого себя
ErrorMessageHint = "Извените, но вы ввели значение уже имеющееся в данной таблице. \nПроверьте правильность введённого значения.";
//...
ShowMessage(ErrorMessageHint);
}
Конечно, при этом надо знать описатель ошибки. Но кто мешает получить его опытным путём.
Так переопределяеш Application->OnException:
При таком подходе, в объщем случае, не нужны try и catch, и почти не нужна проверка, т.к. при внезапном рассоединении от базы, максимул, что произойдёт - это потеряются данные.
...
При таком подходе, в объщем случае, не нужны try и catch, и почти не нужна проверка, т.к. при внезапном рассоединении от базы, максимул, что произойдёт - это потеряются данные.
Потеря данных при работе с базой - ИМХО самое существенное что может произойти. Это первое. Второе - необработка исключения по месту возникновения - крайне порочный стиль разработки. С одной стороны - это выглядит вполне грамотно - все исключения обрабатываются в одном месте, но в реальности все далеко не так сладко, как выглядит, по сути это единственное достоинство данного метода. Потеря данных - это первое, потеря текущего контекста операции - это второе, если приложение состоит более чем из одного модуля - в реальности это приведет к неоднозначному поведению приложения и необходимости сложного механизма возврата в нормальное состояние - это третье.
Предложенный уровень перехвата исключений - это крайний метод, позволяющий хоть както корректно завершить приложение в случае непредвиденного исключения - но никак не нормальное поведение программы. Поэтому, любая операция с базой должна сопровождаться обработкой исключений - иначе проблем будет выше головы ИМХО.
У меня все обработчики работающие с базой имеют try catch. Все работает нормально. Просто интересовала ситуация: данные загружены в грид, пользователь работает с ними, потом пользователь ушел пить кофе, пришел а связь с базой тем временем пропала. Пользователь начал снова работать и соотвественно он получить ошибку.
если так, то да: пинг по таймеру. ну или попытка нового коннекта... как уж больше нравится, а то ведь может быть такое что сервак пингуется а сервак БД на нём упал. :)