Есть такая проблема. Моё приложение создаёт SQLConnection и держит его в течение всей работы.
Возникает необходимость отловить тот момент, когда соединение с SQL-сервером разорвётся по любым причинам. Например, стал недоступен SQLServer и т.п.
Как это можно сделать?
Hello, Eugene!
ES> Есть такая проблема. Моё приложение создаёт SQLConnection и держит его ES> в течение всей работы. Возникает необходимость отловить тот момент, ES> когда соединение с SQL-сервером разорвётся по любым причинам. Например, ES> стал недоступен SQLServer и т.п. Как это можно сделать?
Hello, DmitryMS!
D> The StateChange event is not raised unless you explicitly call Close or D> Dispose. For more information, see Working with Connection Events.
D> But sure you can still run a low priority process to check that D> connection state...
Здравствуйте, GarryIV, Вы писали:
GIV>Hello, DmitryMS!
D>> The StateChange event is not raised unless you explicitly call Close or D>> Dispose. For more information, see Working with Connection Events.
D>> But sure you can still run a low priority process to check that D>> connection state...
GIV>Это не дает 100% гарантии
В случае если связь была нарушена, то есть сеть где-то перестала работать, то об этом можно узнать только получив ICMP пакет от какого-нибудь маршрутизатора с сообщением об отстутствии связи (либо по таймауту TCP). А этот пакет (как и таймаут) возникнет только при попытке воспользоваться открытым соединением. Попытка воспользоваться соединением произойдет где-нибудь в глубинах кода при выполнении какого-нибудь cmd.Execute, rs.Open и т.п.
То есть бороться с этим можно только хорошо продуманой архитектурой приложения. Так, чтобы исключение возникшее где-нибудь в cmd.Execute, выплыло в какой-нибудь обработчик Button1_Click. При этом пользователь будет проинформирован о проблеме, команда пользователя не будет выполнена (но будет корректно отменена), и после этого благополучно сработает событие StateChange event, в результате чего приложение перейдет в режим работы "Offline"
Я не уверен на счет порядка, StateChange сработает после выхода из Button1_Click или между cmd.Execute и возникновением исключения. Но это всегда можно узнать из документации или поставить экперимент.
Здравствуйте, Eugene Sh, Вы писали:
ES>Есть такая проблема. Моё приложение создаёт SQLConnection и держит его в течение всей работы. ES>Возникает необходимость отловить тот момент, когда соединение с SQL-сервером разорвётся по любым причинам. Например, стал недоступен SQLServer и т.п. ES>Как это можно сделать?
Вообще-то это идеологически неправильно. Если будет много приложений и каждое будет держать соединение открытым, пиная его время от времени, то элементарно Connection Pool переполнится. Правильней создавать соединение в начале работы программы, потом просто держать этот объект, открывая соединение по необходимости и закрывая соединение каждый раз после использования. Если это будет один и тот же объект, то он будет просто запулен и будет открываться намного быстрей. А если держать соединение открытым часами, пока программа не завершится... гнять таких программистов.
Здравствуйте, Аноним, Вы писали:
А>Вообще-то это идеологически неправильно. Если будет много приложений и каждое будет держать соединение открытым, пиная его время от времени, то элементарно Connection Pool переполнится. Правильней создавать соединение в начале работы программы, потом просто держать этот объект, открывая соединение по необходимости и закрывая соединение каждый раз после использования. Если это будет один и тот же объект, то он будет просто запулен и будет открываться намного быстрей. А если держать соединение открытым часами, пока программа не завершится... гнять таких программистов.
Согласен, что это не хорошо. У меня было 2 варианта на выбор:
1) Создавать коннект каждый раз, когда он нужен. Это плохо.
2) Сделать так, как я описал. Этот вариант мне тоже не очень нравился.
Про третий вариант, описанный вами, я не знал.
А, вообще, я пишу сервис. Это накладывает дополнительные ограничения?
Hello, Eugene!
А>> Вообще-то это идеологически неправильно. Если будет много приложений и А>> каждое будет держать соединение открытым, пиная его время от времени, А>> то элементарно Connection Pool переполнится. Правильней создавать А>> соединение в начале работы программы, потом просто держать этот объект, А>> открывая соединение по необходимости и закрывая соединение каждый раз А>> после использования. Если это будет один и тот же объект, то он будет А>> просто запулен и будет открываться намного быстрей. А если держать А>> соединение открытым часами, пока программа не завершится... гнять таких А>> программистов.
ES> Согласен, что это не хорошо. У меня было 2 варианта на выбор: ES> 1) Создавать коннект каждый раз, когда он нужен. Это плохо.
Это обычная практика. Это плохо если нет конекшн пулинга. Ежели он есть то очень даже хорошо.
ES> 2) Сделать так, как я описал. Этот вариант мне тоже не очень нравился.
ES> Про третий вариант, описанный вами, я не знал.
Это тот же самый п1 только слекга модифицированный. Создание объекта соединения по времени сущие мелочи по сравнению с обращением к БД.
ES> А, вообще, я пишу сервис. Это накладывает дополнительные ограничения?
Нет. Только надо учитавать что сервисы работают из под другой учетной записи...
Согласен, что это не хорошо. У меня было 2 варианта на выбор:
1) Создавать коннект каждый раз, когда он нужен. Это плохо.
Эт почему это?Из предписания Верховного Суда:
1) Главе ЦИК — признать выборы недействительными...
2) Компьютерному отделу ЦИК — удалить Януковича из папки Избранное...
ES>> Согласен, что это не хорошо. У меня было 2 варианта на выбор: ES>> 1) Создавать коннект каждый раз, когда он нужен. Это плохо. GIV>Это обычная практика. Это плохо если нет конекшн пулинга. Ежели он есть то очень даже хорошо.
Набрёл тут в MSDN на одну статью: ms-help://MS.MSDNQTR.2003OCT.1033/cpguide/html/cpconConnectionPoolingForSQLServerNETDataProvider.htm
Там говорится, что конекшн пул поддерживается автоматически. То есть, если мы создадим коннект, потом закроем его, а потом опять захотим создать такой же коннект, то новый коннект возьмётся из пула.
Исходя из этого можно сделать вывод, что первый вариант — вполне подходящий?
А>Вообще-то это идеологически неправильно. Если будет много приложений и каждое будет держать соединение открытым, пиная его время от времени, то элементарно Connection Pool переполнится.
Можно его не использовать.
А> Правильней создавать соединение в начале работы программы, потом просто держать этот объект, открывая соединение по необходимости и закрывая соединение каждый раз после использования.
Не всегда это решение единственно верное.
А> А если держать соединение открытым часами, пока программа не завершится... гнять таких программистов.
Откуда такая нетерпимость к инакомыслию, коллега?
А>Вообще-то это идеологически неправильно. Если будет много приложений и каждое будет держать соединение открытым, пиная его время от времени, то элементарно Connection Pool переполнится. Правильней создавать соединение в начале работы программы, потом просто держать этот объект, открывая соединение по необходимости и закрывая соединение каждый раз после использования. Если это будет один и тот же объект, то он будет просто запулен и будет открываться намного быстрей. А если держать соединение открытым часами, пока программа не завершится... гнять таких программистов.
Ты попробуй конектиться к Interbase периодически Обычно на конект уходит несколько секунд... вот и порушилась ваша методика — ваша программа тормоз
--
То, что вы уникальны еще не значит, что от вас есть толк
Hello, Eugene!
ES> Здравствуйте, GarryIV, Вы писали:
ES>>> Согласен, что это не хорошо. У меня было 2 варианта на выбор: ES>>> 1) Создавать коннект каждый раз, когда он нужен. Это плохо. GIV>> Это обычная практика. Это плохо если нет конекшн пулинга. Ежели он GIV>> есть то очень даже хорошо.
ES> Набрёл тут в MSDN на одну статью: ms-help://MS.MSDNQTR.2003OCT.1033/cpguide/html/cpconConnectionPoolingForSQLServerNETDataProvider.htm ES> Там говорится, что конекшн пул поддерживается автоматически. То есть, ES> если мы создадим коннект, потом закроем его, а потом опять захотим ES> создать такой же коннект, то новый коннект возьмётся из пула. Исходя из ES> этого можно сделать вывод, что первый вариант — вполне подходящий?
Здравствуйте, Eugene Sh, Вы писали:
ES>Есть такая проблема. Моё приложение создаёт SQLConnection и держит его в течение всей работы. ES>Возникает необходимость отловить тот момент, когда соединение с SQL-сервером разорвётся по любым причинам. Например, стал недоступен SQLServer и т.п. ES>Как это можно сделать?
Перед обращением к базе выполняем для этого коннекта
SELECT 1
обрабатываем ошибку, если надо поднимаем соединение