Переключатели AppContext в SqlClient

Область применения: .NET Framework .NET .NET Standard

Скачать ADO.NET

Класс AppContext позволяет SqlClient предоставлять новые функциональные возможности, продолжая поддерживать вызывающие объекты, которые зависят от предыдущего поведения. Пользователи могут отказаться от изменения в поведении, задав определенные параметры AppContext.

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

Включение MultiSubnetFailover по умолчанию

Область применения: .NET Framework; .NET; .NET Standard

(Доступно начиная с версии 7.0)

Для глобальной настройки MultiSubnetFailover=true без изменения отдельных строк соединения установите переключатель Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault AppContext на true при запуске приложения:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault", true);

Этот переключатель также можно включить в App.Config:

<runtime>
  <AppContextSwitchOverrides value="Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault=true" />
</runtime>

При включении все подключения ведут себя так, как будто MultiSubnetFailover=true заданы в строке подключения. Этот параметр отключен по умолчанию.

Включение мультиплексирования пакетов для асинхронных операций чтения

Область применения: .NET Framework; .NET; .NET Standard

(Доступно начиная с версии 7.0)

Мультиплексирование пакетов повышает производительность больших операций асинхронного чтения, таких как ExecuteReaderAsync с большими результирующих наборами, сценариями потоковой передачи или получением массовых данных. Эта функция управляется двумя переключателями AppContext, которые должны быть выбраны пользователем. Установка обоих переключателей на false включает новый асинхронный путь обработки:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseCompatibilityAsyncBehaviour", false);
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseCompatibilityProcessSni", false);

По умолчанию оба параметра установлены в состояние true, сохраняющее существующее (совместимое) поведение.

Включение расширения компонента агента пользователя

Область применения: .NET Framework; .NET; .NET Standard

(Доступно начиная с версии 7.0)

Когда переключатель Switch.Microsoft.Data.SqlClient.EnableUserAgent AppContext включен, драйвер отправляет данные пользовательского агента на сервер в рамках соединения. Эта информация помогает устранять неполадки и квалифицировать использование драйверов по версиям и операционной системе. Этот параметр отключен по умолчанию. Чтобы включить его, задайте для параметра AppContext значение true при запуске приложения:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableUserAgent", true);

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

Область применения: .NET Framework; .NET; .NET Standard

Начиная с Microsoft.Data.SqlClient 2.0 десятичные данные округляются по умолчанию, как и в SQL Server. Чтобы включить прежнее поведение усечения, можно при запуске приложения установить переключатель AppContext Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal в значение true:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal", true);

Включение управляемых сетей в Windows

Область применения: .NET; .NET Standard

(Доступно начиная с версии 2.0)

В Windows SqlClient по умолчанию использует собственную реализацию сетевого интерфейса SNI. Чтобы обеспечить использование управляемой реализации SNI, установите переключатель Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows AppContext на true при запуске приложения:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);

Этот параметр переключает поведение драйвера на использование управляемой сетевой реализации в .NET Core 2.1+ и .NET Standard 2.0+ в Windows, устраняя все зависимости от собственных библиотек для библиотек Microsoft.Data.SqlClient. Он предназначен только для тестирования и отладки.

Примечание.

При сравнении с собственной реализацией существуют некоторые известные различия. Например, управляемая реализация не поддерживает недоменную аутентификацию Windows.

Отключить прозрачное разрешение сетевых IP-адресов

Область применения: .NET Framework

Прозрачное разрешение IP-адресов сети (TNIR) представляет собой улучшенную версию существующей функции MultiSubnetFailover. TNIR влияет на последовательность подключений драйвера, когда первый разрешенный IP-адрес имени узла не отвечает и имеется несколько IP-адресов, связанных с именем этого узла. Комбинация TransparentNetworkIPResolution и MultiSubnetFailover выбирает последовательность подключения:

Прозрачное разрешение IP-адресов в сети MultiSubnetFailover Последовательность подключений
Истина Истина TransparentNetworkIPResolution не учитывается. Драйвер параллельно пытается подключиться к IP-адресам, полученным при DNS-разрешении, и завершает аутентификацию с первым ответившим сервером.
Истина Ложь Драйвер выполняет несколько раундов подключения для IP-адресов, полученных при DNS-разрешении, с минимальным тайм-аутом 500 миллисекунд для первой попытки и с постепенно увеличивающимися тайм-аутами для каждой следующей попытки, пока соединение не будет успешно установлено или не будет достигнут общий Connect Timeout.
Ложь Истина Драйвер параллельно пытается подключиться к IP-адресам, полученным при DNS-разрешении, и завершает аутентификацию с первым ответившим сервером.
Ложь Ложь Драйвер последовательно пытается использовать каждый IP-адрес, полученный при DNS-разрешении, пока одна из попыток не завершится успешно или не будет достигнут Connect Timeout.

TransparentNetworkIPResolutionвключена по умолчанию в .NET Framework и MultiSubnetFailover по умолчанию отключена. В .NET 5 и более поздних версиях TransparentNetworkIPResolution не является распознаваемым ключевым словом строки подключения, и его задание (с любым значением) приводит к возникновению ArgumentException (KeywordNotSupported). В этих версиях учитывается только MultiSubnetFailover. Остальная часть этого раздела (автоматическое переопределение, режимы отказа в следующем предупреждении и переключатель AppContext) применяется к .NET Framework.

Подсказка

Устанавливайте MultiSubnetFailover=True в каждой строке подключения независимо от версии .NET и от того, является ли целевой системой Azure SQL или локальный SQL Server. MultiSubnetFailover=True выбирает ветвь кода для параллельного подключения, которая быстро находит первую ответившую реплику. В .NET Framework он также обходит последовательный цикл повторного повтора TNIR за IP, который является распространённой причиной долгих задержек соединения и тайм-аутов при предварительной аутентификации.

В .NET Framework, если параметр TransparentNetworkIPResolution не указан в строке подключения, драйвер автоматически отключает TNIR, если источник данных является распознанной конечной точкой Azure SQL, если ключ Authentication имеет значение любого метода Microsoft Entra ID (Active Directory Password, Active Directory Integrated, Active Directory Interactive, Active Directory Service Principal, Active Directory Device Code Flow, Active Directory Managed Identity, Active Directory MSI, Active Directory Default или Active Directory Workload Identity), или если задано свойство SqlConnection.AccessToken. Для суффиксов конечных точек, которые распознаёт драйвер, см. TransparentNetworkIPResolution запись в SqlConnection.ConnectionString.

Явное TransparentNetworkIPResolution значение обходит это автоматическое поведение: True активирует TNIR и False безусловно отключает TNIR. Чтобы восстановить автоматическое поведение, удалите ключевое слово из строка подключения. Автоматическое переопределение также не применяется, когда строка подключения указывает на Azure SQL через пользовательское CNAME или vanity DNS-имя, суффикс которого не распознается как Azure SQL-endpoint. Автоматическое переопределение применяется именно к Azure SQL; для локальных развертываний SQL Server оно не срабатывает, поэтому там TNIR включён по умолчанию.

Длительные задержки подключения на .NET Framework

В .NET Framework TransparentNetworkIPResolution=True (по умолчанию) может вызывать длительные задержки соединения и тайм-ауты при предварительной аутентификации, когда целевой DNS-имя разрешается на несколько IP, а один из предыдущих IP нездоров, устаревший или недоступен. TNIR последовательно проверяет разрешённые IP и увеличивает тайм-аут на попытку в каждом раунде, пока не достигнет общего Connect Timeout значения. Обычно вы наблюдаете неожиданно долгую задержку соединения, которая заканчивается такой ошибкой:

Connection Timeout Expired.  The timeout period elapsed while attempting to consume the pre-authentication handshake acknowledgement.  This could be because the pre-authentication handshake failed or the server was unable to respond back in time.

Этот паттерн проявляется в нескольких топологиях:

  • База данных SQL Azure, Управляемый экземпляр SQL Azure или база данных SQL в Microsoft Fabric. Шлюз Azure SQL направляет каждый запрос на аутентификацию на серверную реплику. Когда маршрутизированное соединение завершается сбоем, TNIR повторно пытается подключиться к выбранному внутреннему серверу, не возвращаясь к шлюзу для повторной маршрутизации, что увеличивает задержку при переключении на резервный внутренний сервер.
  • Локальный SQL Server за слушателем группы доступности Always On, DNS-имя которого разрешается на несколько IP-реплик. TNIR последовательно пытается использовать устаревшую запись DNS или неработоспособный IP-адрес реплики, прежде чем достигает работоспособной реплики.
  • Экземпляры отказоустойчивого кластера с прослушивателем кластера с несколькими подсетями, или любая другая конфигурация, в которой целевое DNS-имя имеет несколько записей A/AAAA (например, DNS round-robin).

Чтобы избежать такого поведения, в строка подключения установитеMultiSubnetFailover=True:

MultiSubnetFailover=True

Эта рекомендация работает для всех версий .NET и охватывает как Azure SQL, так и локальный SQL Server. Когда MultiSubnetFailover=True, драйвер игнорирует TransparentNetworkIPResolution, пытается параллельно использовать DNS-разрешённые IP-адреса и завершает аутентификацию с первой отзывчивой копией. Несмотря на название, MultiSubnetFailover относится к любому слушателю, DNS-имя которого разрешается в несколько целевых IP-адресов, независимо от того, находятся ли эти IP-адреса в разных подсетях, и его можно безопасно использовать на автономных серверах, DNS-имя которых разрешается в один IP-адрес.

Для управления на уровне всего процесса без редактирования каждой строки подключения используйте переключатель AppContext Enable MultiSubnetFailover by default.

Отключите TNIR с помощью переключателя AppContext

Чтобы изменить значение по умолчанию для TransparentNetworkIPResolution с true на false в .NET Framework, при запуске приложения задайте переключателю AppContext Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString значение true. Этот переключатель изменяет значение по умолчанию только если в строке подключения отсутствует TransparentNetworkIPResolution; он не переопределяет явно заданное значение.

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString", true);

Дополнительные сведения об установке этих свойств см. в документации по свойству SqlConnection.ConnectionString.

Включение минимального времени ожидания при входе

Область применения: .NET Framework; .NET; .NET Standard

Чтобы предотвратить бесконечное ожидание при попытке входа, можно установить переключатель Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin AppContext на true при запуске приложения:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin", false);

Отключить блокирующее поведение ReadAsync

Область применения: .NET Framework; .NET; .NET Standard

Начиная с версии 3.0, работает ReadAsync асинхронно. Предыдущие версии выполняют ReadAsync синхронно и блокируют вызывающий поток в .NET Framework. Для контроля этого блокирующего поведения установите переключатель Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking AppContext на true или false при запуске приложения:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking", false);

Включить поведение rowversion null

Область применения: .NET Framework; .NET; .NET Standard

Начиная с версии 3.0, если rowversion имеет значение null, SqlDataReader возвращает значение DBNull вместо пустого byte[]. Чтобы включить устаревшее поведение возврата пустого byte[], включите переключатель AppContext Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior при запуске приложения.

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior", true);

Скрытие предупреждения о небезопасном протоколе TLS

Область применения: .NET Framework; .NET; .NET Standard

(Доступно начиная с версии 4.0.1)

При использовании Encrypt=false в строка подключения консоль выдаёт предупреждение о безопасности, если версия TLS — 1.2 или ниже. Подавите это предупреждение, включив следующий переключатель AppContext при запуске приложения:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning", true);

Игнорировать резервный партнер, предоставленный сервером

Область применения: .NET Framework; .NET; .NET Standard

(Доступно начиная с версий 5.1.8, 6.0.4 и 6.1.3)

После переключения при отказе информация о партнере переключения при отказе, предоставляемая сервером, имеет приоритет над информацией о партнере переключения при отказе, указанной в строке подключения. Чтобы при запуске приложения игнорировать сведения о партнере по отработке отказа, предоставляемые сервером, и учитывать только сведения о партнере отработки отказа, предоставленные в строке подключения, включите этот переключатель AppContext:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.IgnoreServerProvidedFailoverPartner", true);

Обеспечение тайм-аута соединения в режиме простоя

Область применения: .NET Framework; .NET; .NET Standard

Начиная с версии 7.1.0-preview2, ключевое слово строки подключения Connection Idle Timeout настраивает длительность простоя в секундах, по истечении которой соединение в пуле может быть удалено из пула (по умолчанию — 300; значение 0 отключает истечение времени простоя). Подходящее соединение удаляется при последующем извлечении или во время очередного цикла обслуживания, поэтому точный момент может варьироваться в зависимости от реализации пула и периодичности обслуживания. Ключевое слово действует только в том случае, если прежнее поведение тайм-аута бездействия отключено. Если переключатель имеет значение по умолчанию true, пул сохраняет прежнее поведение, и ключевое слово не оказывает никакого влияния.

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseLegacyIdleTimeoutBehavior", false);

Включить пул соединений V2

Область применения: .NET Framework; .NET; .NET Standard

Начиная с версии 6.1, SqlClient включает альтернативную, экспериментальную реализацию пула соединений (V2). Пул V1 остаётся по умолчанию (переключатель по умолчанию установлен на false). Чтобы присоединиться к пулу V2, включите переключатель Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2 AppContext при запуске приложения.

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2", true);

Учитывать время ожидания в пуле в пределах тайм-аута подключения

Область применения: .NET Framework; .NET; .NET Standard

Начиная с версии 7.1.0-preview2, время, затраченное на ожидание подключения из пула подключений, может засчитываться в лимит времени Connect Timeout, отведённый вызывающей стороне, поэтому ожидание в пуле подключений и попытка установить сетевое соединение используют один общий тайм-аут. Когда переключатель установлен в значение по умолчанию false, операции пула получают полный Connect Timeout, а попытка сетевого подключения — ещё один полный бюджет.

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseOverallConnectTimeoutForPoolWait", true);

Вернуться к устаревшему чередованию аварийного переключения при ошибках входа

Область применения: .NET Framework; .NET; .NET Standard

Начиная с версий 7.1.0-preview2, при подключении с конфигурированным резервным режимом SqlClient больше не переключается на партнёра по резервированию ошибок SQL, возвращаемых во время входа. Чтобы вернуться к прежнему поведению чередования, включите переключатель AppContext Switch.Microsoft.Data.SqlClient.UseLegacyFailoverAlternationOnLoginSqlErrors при запуске приложения. Переключатель по умолчанию установлен на false.

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseLegacyFailoverAlternationOnLoginSqlErrors", true);

Учитывать явно заданное нулевое значение масштаба для параметров vartime

Область применения: .NET Framework; .NET; .NET Standard

По умолчанию SqlClient отправляет шкалу 7, если вы явно устанавливаете шкалу на 0 для параметров datetime2, datetimeoffset или time . В версии 6.0 и более поздних версиях установите Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour в значение false при запуске приложения, чтобы сохранить явно заданный масштаб, равный 0. Переключатель по умолчанию установлен на true.

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour", false);