Автоматическое восстановление, когда общая сетевая ошибка Dbnetlib ConnectionWrite приводит к отключению соединений ADO в приложениях Delphi?

Googling это сообщение об ошибке ADO указывает, что оно обычно встречается в ASP.NET разработка, но я не нашел много упоминаний о том, когда это происходит в приложениях Delphi. У нас есть некоторые сайты клиентов, которые испытывают временные проблемы с сетью, и это симптоматическое сообщение об ошибке. Мы можем легко дублировать его в office testing; просто закройте службу MS SQL Server, пока ваш объект delphi TADOConnection подключен к базе данных на этом экземпляре сервера, и вы получите это исключение:

   [DBNETLIB][ConnectionWrite (send()).]General network error. Check your network documentation.

Да, поймать это исключение, и вы знаете (или вы?), что эта ошибка произошла. За исключением того, что это приложение 800 KLOC+ с более чем 10,000 try-кроме блоков вокруг действий базы данных, любой из которых может потерпеть неудачу с этой ошибкой.

TADOConnection имеет некоторые события ошибок, ни один из которых не срабатывает в этом случае. Тем не менее само соединение ADO неисправен, как только это происходит, даже при перезапуске базы данных SQL, TADOConnection.Соединенные остатки верно, но это ложь. Он действительно в неисправном состоянии.

Итак, мой вопрос:

можете ли вы обнаружить это неисправное состояние и восстановить из него каким-либо образом, что меньше работы, чем в 10 000 отдельных попыток, кроме блоков и установки некоторой глобальной "повторно подключить глобальную переменную ADO"?

Я надеюсь, что есть способ войти в TADOConnection.ConnectionObject (базовый необработанный объект OLEDB COM ADO) и обнаружить это условие неисправности существует, когда мы запускаем новый запрос, так что мы можем сбросить ADOConnection и продолжить при следующем запуске запроса. Поскольку наш код организован таким образом, что позволил бы нам обнаружить это "после сбоя" гораздо легче, чем это позволило бы нам сделать это так, как я бы сделал это в демонстрационном приложении 10 line.

это другой так вопрос спрашивает, почему это происходит, то есть не то, что я прошу, пожалуйста, не дай мне "предупреждение" ответы, я уже знаю о них, я ищу метод восстановления и обнаружения застопорившихся ADO-соединений, кроме ловли исключений. На самом деле, это хороший пример неправильных исключений; ADO-объект schrodingers-cat в этом режиме сбоя.

Я знаю о статьях базы знаний MS и различных решениях, плавающих по интернету. Я спрашиваю о восстановлении без потери данных клиента, как только условие ошибки (которое часто является переходным в нашем ситуация) прояснилась. Это означает, что мы замораживаем наше приложение, показываем исключение клиенту, и когда клиент нажимает повторить или продолжить, мы пытаемся восстановить и продолжить. обратите внимание, что наш существующий код делает миллион try-except-log-and-continue кода, который будет мешать нам, поэтому я ожидаю, что кто-то ответит, что обработчик приложений для необработанных исключений-лучший способ, но, к сожалению, мы не можем его использовать. Я действительно надеюсь, однако, что можно обнаружить замороженный / неисправный / мертвый ADO объект подключения.

вот что у меня есть:

try
  if fQueryEnable and ADOConnection1.Connected then begin
    qQueryTest1.Active := false;
    qQueryTest1.Active := true;
    Inc(FQryCounter);
    Label2.Caption := IntToStr(qQueryTest1.RecordCount)+' records';

  end;
except
      on E:Exception do begin
         fQueryEnable := false;
         Memo1.Lines.Add(E.ClassName+' '+E.Message);
         if E is EOleException and Pos('DBNETLIB',E.Message)>0 then begin
            ADOConnectionFaulted := boolean; { Global variable. }
         end;
         raise;
      end;
end;

проблема с вышеуказанным решением заключается в том, что мне нужно скопировать и вставить его около 10 000 мест в моем приложении.

2 ответов


Ну никто не ответил на этот вопрос, и я думаю, что некоторым будет полезно.

вот что я узнал:

  • нет надежных ситуаций, когда в тестовой среде можно воспроизвести эту общую сетевую ошибку. То есть, мы имеем дело с невоспроизводимыми результатами, в которых многие разработчики прыгают в злой хакерство в попытке "обезьянничать" свои сломанные системы.

  • фиксация основная ошибка всегда и везде была лучше, чем исправление ее в коде, когда библиотека SQL дает "общую сетевую ошибку". Ни один ремонт никогда не был показан возможным, потому что обычно это означает ,что "сеть настолько ненадежна, что сам TCP отказался от доставки моих данных", это происходит, когда:

    • у вас плохой сетевой кабель.

    • у вас есть дубликаты IP-адресов в сети.

    • у вас есть дуэльные DHCP-серверы обрабатывают разные шлюзы по умолчанию.

    • у вас есть локальные сегменты ethernet, которые имеют плохую связь между ними.

    • у вас есть коммутатор ethernet или концентратор, который терпит неудачу.

    • вы периодически блокируются неисправным брандмауэром.

    • ваш клиент может что-то изменить в своей сети, и теперь не может использовать ваше программное обеспечение. (Этот последнее на самом деле происходит больше, чем вы могли бы подумать)

    • кто-то, возможно, настроил псевдоним SQL, используя cliconfg или другие элементы конфигурации на стороне клиента, специфичные для параметров реестра одной рабочей станции, и эта локальная конфигурация может привести к плохому поведению, которое трудно диагностировать и может быть ограничено одной или несколькими рабочими станциями в большой сети.

ничего из вышеперечисленного не может быть обнаружено и сообщается либо в ПТС или SQL уровне. Когда SQL, наконец, сдается, и он дает эту "общую сетевую ошибку", никакое количество уговоров из моего программного обеспечения не заставит его отказаться, и даже если бы это было так, я бы делал "try/except/ignore" antipattern. Эта ошибка настолько серьезна, что мы должны поднять ее до пользователя, зарегистрировать ее на диск в журнале ошибок, отказаться (выйти из программы) и сообщить пользователю, что сетевое соединение не работает.


Я видел, что это происходит из-за плохого кодирования..

Если вы открываете набор записей с помощью соединения и повторно используете это же соединение в цикле для другого набора записей, пока первое соединение не закрыто, это может вызвать аналогичные ошибки.

другой случай очень редко в веб-приложениях, когда пул приложений рециркулирует, вы можете получить аналогичную ошибку.

У нас есть разные сайты на одном сервере, где я заметил, что с то же приложение, но с различными настройками, только один сайт вызывает эту проблему. Это приводит к вышеуказанным выводам.

этот блог помог мне найти вопросы:

http://offbeatmammal.hubpages.com/hub/Optimising_SQL_Server