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

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

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

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

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

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

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

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

это другой так вопрос спрашивает, почему это происходит, то есть не то, что я прошу, пожалуйста, не дай мне "предупреждение" ответы, я уже знаю о них, я ищу метод восстановления и обнаружения застопорившегося соединения, отличный от перехвата исключений. Фактически, это хороший пример исключений, которые пошли не так; 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 или другие элементы конфигурации на стороне клиента, специфичные для параметров реестра одной рабочей станции, и эта локальная конфигурация может привести к плохому поведению, которое трудно диагностировать и может быть ограничено одной или несколькими рабочими станциями в большой сети.

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

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

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

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

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

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

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