Как вы справляетесь с ошибками транспортного уровня в SqlConnection?

Время от времени в крупномасштабном .NET-приложении вы можете видеть это исключение при попытке выполнить запрос:

System.Data.SqlClient.SqlException: A transport-level error has occurred when sending the request to the server.

Согласно моим исследованиям, это происходит «просто так», и мало что можно сделать, чтобы предотвратить это. Это не происходит в результате неправильного запроса и, как правило, не может быть продублировано. Он просто возникает, может быть, раз в несколько дней в загруженной системе OLTP, когда TCP-соединение с базой данных по какой-то причине ухудшается.

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

У кого-нибудь есть альтернативные решения?

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

John Christensen 19.08.2008 21:41

Это не следует происходит даже при большом объеме транзакций. Мы выполняем в среднем 25 000 транзакций в секунду на SQL Server 2005 Standard, и мы не получаем эту ошибку. (Если кластер не выходит из строя, что происходит каждые 12+ месяцев, а не каждые несколько дней.) Без дополнительной информации это звучит так, как будто существует проблема с сетью между вашим сервером базы данных и вашими серверами приложений. Вы можете разместить дополнительную информацию?

Portman 22.08.2008 16:27

@Portman, я подозреваю, что это из-за дрянной встроенной сетевой карты Dell, которую я вынужден использовать, поскольку оба моих слота PCIe заняты картами HBA, подключенными к моему DAS. Я перехожу на более крупную машину, чтобы установить (намного) лучшую сетевую карту Intel. Как у вас кластеризация со стандартной версией? Это особенность Enterprise Edition.

Eric Z Beard 24.08.2008 05:25

кластеризация, доставка журналов и зеркалирование доступны в стандартной версии. http://www.microsoft.com/sql/prodinfo/features/compare-featu‌ res.mspx

Portman 27.08.2008 00:15

Насколько я могу судить, 20 класс - это транспортный уровень.

Joshua 19.08.2010 21:20
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
32
5
23 727
11

Ответы 11

Вам также следует проверить аппаратное подключение к базе данных.

Возможно, эта ветка будет вам полезна: http://channel9.msdn.com/forums/TechOff/234271-Conenction-forcible-closed-SQL-2005/

Я использую уровень надежности для своих команд БД (абстрагированных в интерфейсе репозитория). По сути, это просто код, который перехватывает любое ожидаемое исключение (DbException, а также InvalidOperationException, которое возникает при проблемах с подключением), регистрирует его, собирает статистику и повторяет все снова.

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

PS: Подробнее об этом здесь (вместе с простым способом определения надежности с помощью DSL перехвата)

Чтобы ответить на ваш исходный вопрос:

Более элегантный способ обнаружить эту конкретную ошибку без анализа сообщения об ошибке - проверить свойство NumberSqlException.

(Это фактически возвращает номер ошибки из первого SqlError в коллекции Errors, но в вашем случае транспортная ошибка должна быть единственной в коллекции.)

У меня такая же проблема. Я спросил своих друзей-сетевых компьютерщиков, и все сказали, что люди здесь ответили: это соединение между компьютером и сервером базы данных. В моем случае проблема была в моем интернет-провайдере или в маршрутизаторе. После обновления роутера проблема исчезла. Но есть ли у вас какие-либо другие случаи пропадания интернет-соединения с вашего компьютера или сервера? Я имел...

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

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

Взгляните на параметры реестра для настройки TCP / IP в Windows. В частности, вы хотите посмотреть TcpMaxDataRetransmissions и, возможно, TcpMaxConnectRetransmissions. По умолчанию они равны 5 и 2 соответственно, попробуйте немного увеличить их в клиентской системе и продублировать ситуацию загрузки.

Не сходи с ума! TCP удваивает тайм-аут с каждой последующей повторной передачей, поэтому поведение тайм-аута для плохих соединений может стать экспоненциальным для вас, если вы увеличите его слишком сильно. Насколько я помню, повышение TcpMaxDataRetransmissions до 6 или 7 решало нашу проблему в подавляющем большинстве случаев.

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

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

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

Удачи.

Этот Сообщение блога от Майкл Аспенгрен объясняет сообщение об ошибке «Произошла ошибка транспортного уровня при отправке запроса на сервер».

У меня была такая же проблема, хотя и с запросами на обслуживание в базе данных SQL.

Вот что у меня было в журнале ошибок службы:


System.Data.SqlClient.SqlException: при отправке запроса на сервер произошла ошибка транспортного уровня. (поставщик: поставщик TCP, ошибка: 0 - существующее соединение было принудительно закрыто удаленным узлом.)


У меня есть набор тестов C#, который тестирует службу. Служба и БД были на внешних серверах, поэтому я подумал, что это может быть проблемой. Поэтому я развернул службу и БД локально, но безрезультатно. Вопрос продолжился. Набор тестов даже не является жестким тестом производительности, поэтому я понятия не имел, что происходит. Один и тот же тест каждый раз терпел неудачу, но когда я отключил этот тест, другой тест не удался постоянно.

Я пробовал другие методы, предложенные в Интернете, которые тоже не сработали:

  • Увеличьте значения реестра TcpMaxDataRetransmissions и TcpMaxConnectRetransmissions.
  • Отключите параметр «Общая память» в диспетчере конфигурации SQL Server в разделе «Клиентские протоколы» и отсортируйте TCP / IP до 1-го места в списке.
  • Это может произойти, когда вы тестируете масштабируемость с большим количеством попыток подключения клиентов. Чтобы решить эту проблему, используйте служебную программу regedit.exe, чтобы добавить новое значение DWORD с именем SynAttackProtect в раздел реестра HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters \ с данными значения 00000000.

Моим последним средством было использовать старость, говорящую «Попробуй и попробуй еще раз». Поэтому у меня есть вложенные операторы try-catch, чтобы гарантировать, что если соединение TCP / IP потеряно в нижнем протоколе связи, оно не просто откажется от этого, а попытается снова. Теперь это работает для меня, но это не очень элегантное решение.

Спасибо за ответ. Если вы используете пул соединений, попробуйте вызывать SqlConnection.Recycle () каждые, скажем, 10 минут, чтобы убедиться, что если SQLServer уничтожил соединение, ваш пул все еще не пытается его использовать. Если это сработает, сообщите об этом!

TheLegendaryCopyCoder 26.11.2015 13:57

использовать Enterprise Services с транзакционными компонентами

Сегодня утром я столкнулся с транспортной ошибкой в ​​SSMS при подключении к SQL 2008 R2 Express.

Я пытался импортировать CSV с \ r \ n. Я закодировал терминатор строки для 0x0d0x0a. Когда я изменил его на 0x0a, ошибка прекратилась. Я могу менять его туда-сюда и смотреть, как это происходит / не происходит.

 BULK INSERT #t1 FROM 'C:3\Import123.csv' WITH 
      ( FIRSTROW = 1, FIELDTERMINATOR = ',', ROWTERMINATOR = '0x0d0x0a' )

Я подозреваю, что я неправильно пишу терминатор строки, потому что SQL анализирует один символ за раз, когда я пытаюсь передать два символа.

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

Я думаю, проблема заключалась в том, что терминатор строк должен быть одним двоичным значением, которое для SQL-сервера будет записано как 0x0d0a (без второго 0x).

Zastai 05.04.2016 10:13

Привет! Это круто! Я попробую это сегодня вечером!

Phillip Deneka 07.06.2016 00:37

Я просто хотел опубликовать здесь исправление, которое помогло нашей компании установить новое программное обеспечение. С первого дня в файле журнала клиента мы получали следующую ошибку: Сервер не может обработать запрос. ---> Ошибка транспортного уровня при получении результатов от сервера. (поставщик: поставщик TCP, ошибка: 0 - период тайм-аута семафора истек.) ---> Период тайм-аута семафора истек.

Что полностью решило проблему, так это настройка агрегатора ссылок (LAG) на нашем коммутаторе. Наш сервер Dell FX1 имеет резервные оптоволоконные линии, выходящие из задней части. Мы не понимали, что коммутатор, к которому они подключены, должен иметь LAG, настроенный на этих двух портах. Подробности здесь: https://docs.meraki.com/display/MS/Switch+Ports#SwitchPorts-LinkAggregation

Другие вопросы по теме