-
Приветствую Всех! Есть довольно объемный проект. Работа с MSSQL ведется через ADO. До тех пор, пока пользователи все сидели в локальной сети проблем не было. Но вот возникла необходимость подключить удаленных пользователей. Через VPN они "смотрят" в сеть и подключаются к серверу. Периодически у удаленных пользователей отваливается интернет и связь рвется. Пытаюсь решить проблему: перекопал поиском интернет, много обсуждений подобных проблем но практически не нашел решений. Хотя оно думается должно быть на поверхности - уверен что проблема довольно частая. Вариант решения из разряда "по таймеру делать микро запросы к серверу и проверять их корректность обработчиком ошибок" мне показались очень кривыми. Нашел вот такое обсуждение http://www.sql.ru/forum/actualthread.aspx?tid=376842Ошибка отлавливается, происходит пересоединение, после которого все равно вываливается ошибка соединения хотя вроде все пересоеденилось...
-
А тебе, я так думаю, хочется, что бы все, ранее открытые, датасеты, после переподключения остались валидны?
-
>Sergey13 © (20.08.08 12:51) [1] Ну да... есть такое желание
-
Max Zyuzin © (20.08.08 12:08)
Если уничтожить и создать конекшин, тогда переподключишься. но это тоже криво.
Сам искал как это седелать - не нашел.
-
> Ну да... есть такое желание
Нереально. Разве что одним махом отключить все DataSet-ы от коннекшена, запомнить во всех позиции курсора, переподключиться, подсоединить к новому коннекшену все датасеты, переоткрыть каждый, залокейтить на сохранённую позицию. Как-то так.
-
> [2] Max Zyuzin © (20.08.08 14:21)
Коннект отваливается не только у клиента, но и у сервера. И ему глубоко фиолетово ты заново подключаешься или переподключаешься. Он все равно новую сессию открывает, выделяет тебе всякие ресурсы заново и т.д. и т.п. Это я по опыту работы с Ораклом в основном говорю, с МС у меня нет большого опыта общения. Но не думаю, что эти вещи у них сильно различаются.
-
>Ega23 © (20.08.08 14:37) [4] & Sergey13 © (20.08.08 14:59) [5] В общем подумал что позиции курсора можно и не сохранять. Но уже понимаю что придется переоткрывать все активные датасеты.
-
> В общем подумал что позиции курсора можно и не сохранять.
Лучше сохранить. Только не букмарками - они инвалидны после переоткрытия. Запоминай значения ключевых полей.
-
> [6] Max Zyuzin © (20.08.08 15:08) > Но уже понимаю что придется переоткрывать все активные датасеты.
Только надо хорошенько подумать стОит ли это делать, ИМХО. Возможно самым правильным будет вывести пользователю сообщение типа "Связь в сервером потеряна. Перезапустите программу". Чего он там понаоткрывал, в какой последовательности, с какими параметрами? Сможешь однозначно определить? Если приложение достаточно сложное, то можно за чем нибудь не уследить и наделать таких делов, что после них только заявление по собственному писать. ИМХО.
-
Не надо заниматься дурью - для удаленного использовать TClientDataSet с перечиткой по требованию и никакими правками в БД. Клиент будет "зависать" только при перечитках, которые сам же и запускает. При этом ничего не будет "теряться" и данные будут актуализироваться по требованию, что интуитивно прозрачно даже для самого "темного" узера
-
>MsGuns © (20.08.08 15:52) [9] В программе уже сделано очень много ADODataSet, ADOCommand и немного ADOQuery. Заменять их на ClientDataSet не получится
-
Ну тогда веники
-
Последствия визуальности, кардинальное решение в [8], можно и без перезагрузки, а начать с главной формы и переоткрытия (через меню или автоматом). Можно в принципе пересмотреть и подход - ничего не открывать раньше времени и это делать каждый раз при операции. Конечно требует переделки и переосмысления работы.
-
Решил поступить кардинально... [8] всем спасибо.
-
procedure TDM.ReconnectBD;
var DSCount,DSOpenedCount,i:integer;
ms:array[1..100,1..2] of integer;
Begin
MessageDlg('Потеряна связь с сервером базы данных! Попытаемся восстановить...',mtWarning,[mbOk],0);
DSCount:=ADOConnection1.DataSetCount;
DSOpenedCount:=0;
for i:=1 to DSCount do
if ADOConnection1.DataSets[i-1].Active then Begin
DSOpenedCount:=DSOpenedCount+1;
ms[DSOpenedCount,1]:=i;
ms[DSOpenedCount,2]:=ADOConnection1.DataSets[i-1].RecNo;
end;
try
ADOConnection1.Close;
ADOConnection1.Open;
except
if MessageDlg('Ошибка подсоединения к серверу базы данных!',mtError,[mbRetry,mbAbort],0)=mrAbort then Begin MainForm.Close; Exit; end
else ReconnectBD;
end;
try
for i:=1 to DSOpenedCount do Begin
ADOConnection1.DataSets[ms[i,1]-1].Active:=True;
ADOConnection1.DataSets[ms[i,1]-1].RecNo:=ms[i,2];
end;
except
exit;
end;
end; Процедура вызывается в Таймере запросом Select 1 В многооконных приложениях накладнее будет просто предложить юзеру перезайти. Т.к. возможна ситуация, когда будет набран, но не сохранен большой документ.
-
> ms[DSOpenedCount,2]:=ADOConnection1.DataSets[i-1].RecNo;
Сразу фтопку можно выбросить.
-
>BoxTer (25.08.08 12:46) [14]
Замечательная по своему идиотизму и реализации идея
-
Ой, она ещё и рекурсивная..... Какой ужас...
-
использовать отсоединенные дайтасеты а лучше вообще дэйтасеты не использовать
-
а причину указать?
-
> BoxTer (26.08.2008 8:32:19) [19]
Да хотя бы потому что в основе recordset - вот его и надо использовать, а датасет иметь такой как в .NET
-
> а причину указать?
А ты ничего такого не видишь? Я даже строчку кода привёл, за который "фтопку". Конкретно - RecNo. Ещё конкретнее - чуть-чуть подумай.
|