Лена |
Отправлено: 26.12.2006, 14:25 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
В грид при старте приложения загружаются данный из ClientDataset. Допустим пользователь редактирует запись в гриде. В это время прерывается связь с сервером. Обрабатываю эту ситуацию в событии ClientDataSetBeforePost:
CODE |
try{
ADOQueryKey->Open();
}
catch(...)
{
ShowMessage("Не удалось записать в базу. Проверти связь с сервером");
DataSet->Cancel();
//ADOQueryKey->Close();
Abort();
return;
}
|
Все нормально код отрабатывает. Теперь пусть неожиданно связь с сервером появляется, как это обработать, ведь теперь постоянно я получаю ShowMessage не взирая на то, что связь с сервером восстановилась?
Полностью обработчик выглядит так:
CODE |
void __fastcall TDataModule2::ClientDataSetKeyBeforePost(TDataSet *DataSet)
{
if(Form1->DBGrid1->Fields[0]->Value.IsNull() || Form1->DBGrid1->Fields[2]->Value.IsNull()
|| Form1->DBGrid1->Fields[3]->Value.IsNull())
{
sShowMessage("Поля \"Код\", \"Доступ\", и \"Владелец\" должны быть заполнены");
Abort();
}
try{
ADOQueryKey->Open();
}
catch(...)
{
sShowMessage("Не удалось отправить запись в базу. Проверти подключение к серверу");
DataSet->Cancel();
//ADOQueryKey->Close();
Abort();
return;
}
Variant Rez = ADOQueryKey->Lookup("code", Form1->DBGrid1->Fields[0]->AsString, "code");
if(!Rez.IsNull() && Form1->DBGrid1->SelectedIndex == 0)
{
sShowMessage("Такая запись уже есть. Введите другую");
DataSet->Cancel();
ADOQueryKey->Close();
Abort();
}
ADOQueryKey->Close();
| |
|
Tantos |
Отправлено: 26.12.2006, 14:50 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 108
|
Может, тебе попробовать отключаться от сервера и закрывать все датасеты?
|
|
Лена |
Отправлено: 26.12.2006, 15:50 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
QUOTE (Tantos @ 26.12.2006, 14:50) | Может, тебе попробовать отключаться от сервера и закрывать все датасеты? |
Как в этом случае правильно написать обработчик ClientDataSetBeforePost?
Окончательно мне надо, чтобы программа умела правильно обрабатывать сбои в сети. Если сбой то откат записи, если связь появилась, то и приложение ожило.
|
|
Tantos |
Отправлено: 27.12.2006, 05:01 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 108
|
ИМХО, в блоке catch прописывай закрытие все датасетов и соединений. А как ты хочешь выполнить откат, если нет соединения с базой? Кстати, а что за СУБД ты используешь? Если это IB/FB, то в компонентах FIBPLus подобная обработка предусмотрена. Да, рекомендую использовать CachedUpdates, тогда данные в локальном буфере останутся.
Отредактировано Tantos — 27.12.2006, 12:05
|
|
Лена |
Отправлено: 27.12.2006, 17:49 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
QUOTE (Tantos @ 27.12.2006, 05:01) | ИМХО, в блоке catch прописывай закрытие все датасетов и соединений. А как ты хочешь выполнить откат, если нет соединения с базой? Кстати, а что за СУБД ты используешь? Если это IB/FB, то в компонентах FIBPLus подобная обработка предусмотрена. Да, рекомендую использовать CachedUpdates, тогда данные в локальном буфере останутся. |
Редактирую запись, к примеру, пропала связь с сервером. При переходе курсора на новую строку. Возникает событие отправки в базу. В catch можно для отката написать ClientDataSet1->CancelUpdates(); Все это прекрасно работает, но если связь с сервером восстановилась, то для дальнейшей работы приложения необходимо перезапустить все приложение, в противном случае все время продолжает срабатывать catch.
Написала такой обработчик:
CODE |
void __fastcall TDataModule2::ADOConnection1AfterDisconnect(
TObject *Sender)
{
ShowMessage("Пропала связь с сервером");
}
|
Умышленно отключила сеть. Никакого сообщения ShowMessage("Пропала связь с сервером") не появилось.
Оно появиться, если принудительно устанавливать: DataModule2->ADOConnection1->Connected = false;
Мне же, надо отловить в фоновом режиме работы приложения разрыв связи с сервером и сообщить об этом пользователю, а при восстановлении связи с сервером, хочется, чтобы приложение продолжило свою нормальную работу без перезапуска. База данных PostgreSQL.
Есть стандартные решения обработки ситуации проподания связи с сервером базы данныхи затем ее восстановление?
Отредактировано Лена — 27.12.2006, 17:51 |
|
olegenty |
Отправлено: 28.12.2006, 08:54 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
разрыв ты и сейчас отлавливаешь. при разрыве (ИМХО) надо "разорвать" связи всех компонентов с Connection и врубить таймер, по которому будет производиться попытка соединения. в случае, если соединение прошло успешно, вырубить таймер, восстановить все разорванные связи с Connection и продолжить работу. вот как-то так.
|
|
Лена |
Отправлено: 28.12.2006, 10:55 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Может положить на форму компонет Indy и переодически пинговать сервер? В случае пропажи связи, просто сообщить пользователю и предложить закрыть приложение?
Думала есть какие-то стандаратные решения. |
|
olegenty |
Отправлено: 28.12.2006, 14:01 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
то, что сервер пингуется, не означает, что доступен интересующий тебя сервис. в общем случае пингование ничего не даёт. другое дело, что ты можешь сделать два таймера, один — для пингования, другой для попыток соединения после того, как пинг прошёл.
|
|
Gedeon |
Отправлено: 29.12.2006, 16:22 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Я уже где-то писал, но повторюсь, лучше всего с каким-то периодом выполнять простой запрос, типа SELECT GETDATE()
|
|