Przełączniki AppContext w programie SqlClient

Dotyczy: .NET Framework .NET Standard

Pobieranie ADO.NET

Klasa AppContext umożliwia programowi SqlClient udostępnianie nowych funkcji, a jednocześnie obsługę osób wywołujących, którzy zależą od poprzedniego zachowania. Użytkownicy mogą zrezygnować ze zmiany zachowania, ustawiając określone przełączniki AppContext.

SqlClient odczytuje i buforuje każdy przełącznik przy pierwszym użyciu tego przełącznika. Ustaw przełączniki podczas uruchamiania aplikacji, przed użyciem jakichkolwiek typów SqlClient. Zmiana przełącznika po tym, jak SqlClient zapisał jego wartość w pamięci podręcznej, nie ma żadnego efektu.

Domyślnie włącz funkcję MultiSubnetFailover

Dotyczy: .NET Framework; .NET; .NET Standard

(Dostępne od wersji 7.0)

Aby ustawić MultiSubnetFailover=true globalnie bez modyfikowania poszczególnych ciągów połączeń, ustaw przełącznik AppContext Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault na true podczas uruchamiania aplikacji:

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

Możesz również włączyć ten przełącznik w pliku App.Config:

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

Po włączeniu wszystkie połączenia zachowują się tak, jakby MultiSubnetFailover=true było ustawione w parametrach połączenia. Ten przełącznik jest domyślnie wyłączony.

Włączanie multipleksowania pakietów dla operacji odczytu asynchronicznego

Dotyczy: .NET Framework; .NET; .NET Standard

(Dostępne od wersji 7.0)

Multipleksowanie pakietów zwiększa wydajność dużych operacji odczytu asynchronicznego, takich jak ExecuteReaderAsync zestawy dużych wyników, scenariusze przesyłania strumieniowego lub zbiorcze pobieranie danych. Ta funkcja jest kontrolowana przez dwa opcjonalne przełączniki AppContext. Ustawienie obu przełączników na false umożliwia nową ścieżkę przetwarzania asynchronicznego:

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

Domyślnie oba przełączniki to true, co zachowuje istniejące (zgodne) zachowanie.

Włączanie rozszerzenia funkcji agenta użytkownika

Dotyczy: .NET Framework; .NET; .NET Standard

(Dostępne od wersji 7.0)

Gdy przełącznik Switch.Microsoft.Data.SqlClient.EnableUserAgent AppContext jest włączony, sterownik wysyła dane agenta użytkownika do serwera jako część połączenia. Te informacje pomagają w rozwiązywaniu problemów i kwantyfikacji użycia sterowników według wersji i systemu operacyjnego. Ten przełącznik jest domyślnie wyłączony. Aby ją włączyć, ustaw przełącznik AppContext na true przy uruchamianiu aplikacji:

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

Włącz tryb zaokrąglania dziesiętnego

Dotyczy: .NET Framework; .NET; .NET Standard

Począwszy od microsoft.Data.SqlClient 2.0, dane dziesiętne są domyślnie zaokrąglane, podobnie jak w przypadku programu SQL Server. Aby włączyć poprzednie zachowanie polegające na obcinaniu, możesz ustawić przełącznik AppContext Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal na true podczas uruchamiania aplikacji:

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

Włączanie sieci zarządzanej w systemie Windows

Dotyczy: .NET; .NET Standard

(Dostępne od wersji 2.0)

W systemie Windows program SqlClient domyślnie używa natywnej implementacji interfejsu sieciowego SNI. Aby włączyć korzystanie z zarządzanej implementacji SNI, ustaw przełącznik AppContext Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows na true podczas uruchamiania aplikacji:

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

Ten przełącznik zmienia zachowanie sterownika, aby korzystać z zarządzanej implementacji sieciowej w projektach .NET Core 2.1+ i .NET Standard 2.0+ w systemie Windows, eliminując wszystkie zależności od bibliotek natywnych dla biblioteki Microsoft.Data.SqlClient. Służy tylko do testowania i debugowania.

Uwaga / Notatka

Istnieją pewne znane różnice w porównaniu z implementacją natywną. Na przykład zarządzana implementacja nie obsługuje uwierzytelniania Windows poza domeną.

Wyłącz przezroczystą rozdzielczość IP sieci

Dotyczy: .NET Framework

Transparent Network IP Resolution (TNIR) to poprawka istniejącej funkcji MultiSubnetFailover. Funkcja TNIR wpływa na sekwencję połączeń sterownika w przypadku, gdy pierwszy rozpoznany adres IP nazwy hosta nie odpowiada i istnieje wiele adresów IP skojarzonych z nazwą hosta. Kombinacja TransparentNetworkIPResolution i MultiSubnetFailover wybiera sekwencję połączeń:

TransparentNetworkIPResolution MultiSubnetFailover Sekwencja połączeń
Prawda Prawda TransparentNetworkIPResolution jest ignorowana. Sterownik równolegle próbuje adresów IP rozstrzygniętych przez DNS i kończy uwierzytelnianie z tym, który odpowie jako pierwszy.
Prawda Nieprawda Sterownik wielokrotnie próbuje nawiązać połączenie dla adresów IP rozpoznanych przez DNS, z minimalnym limitem czasu wynoszącym 500 milisekund przy pierwszej próbie i stopniowo zwiększanymi limitami czasu dla kolejnych prób, aż połączenie zostanie nawiązane lub do osiągnięcia ogólnego limitu Connect Timeout.
Nieprawda Prawda Sterownik równolegle próbuje adresów IP rozstrzygniętych przez DNS i kończy uwierzytelnianie z tym, który odpowie jako pierwszy.
Nieprawda Nieprawda Sterownik kolejno próbuje każdego adresu IP rozpoznanego przez DNS, aż jedno z połączeń powiedzie się lub zostanie osiągnięty limit Connect Timeout.

TransparentNetworkIPResolutionjest domyślnie włączony w .NET Framework, a MultiSubnetFailover domyślnie wyłączony. W środowisku .NET 5 i nowszych wersjach TransparentNetworkIPResolution nie jest rozpoznawanym słowem kluczowym parametru połączenia, a ustawienie tego parametru (na dowolną wartość) powoduje zgłoszenie wyjątku ArgumentException (KeywordNotSupported). Te wersje obsługują tylko MultiSubnetFailover. Pozostała część tej sekcji (automatyczne zastąpienie, tryby niepowodzenia w poniższym ostrzeżeniu oraz przełącznik AppContext) dotyczy platformy .NET Framework.

Wskazówka

Ustaw MultiSubnetFailover=True na każdym parametry połączenia, niezależnie od wersji .NET czy tego, czy celem jest Azure SQL czy lokalny SQL Server. MultiSubnetFailover=True wybiera ścieżkę kodu dla połączeń równoległych, która szybko znajduje replikę odpowiadającą jako pierwsza. W środowisku .NET Framework omija także sekwencyjną pętlę ponawiania prób TNIR dla poszczególnych adresów IP, która jest częstą przyczyną długich opóźnień nawiązywania połączenia i przekroczeń limitu czasu uzgadniania połączenia przed uwierzytelnieniem.

W środowisku .NET Framework, gdy w parametrach połączenia nie określono elementu TransparentNetworkIPResolution, sterownik automatycznie wyłącza TNIR, gdy źródłem danych jest rozpoznany punkt końcowy usługi Azure SQL, gdy klucz Authentication ma ustawioną dowolną metodę 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 lub Active Directory Workload Identity) albo gdy ustawiono właściwość SqlConnection.AccessToken. Informacje o sufiksach punktów końcowych rozpoznawanych przez sterownik można znaleźć we wpisie TransparentNetworkIPResolution w SqlConnection.ConnectionString.

Wartość jawna TransparentNetworkIPResolution omija to automatyczne zachowanie: True włącza TNIR i False wyłącza TNIR bezwarunkowo. Aby przywrócić automatyczne zachowanie, usuń słowo kluczowe z parametry połączenia. Automatyczne zastępowanie również nie ma zastosowania, gdy parametr połączenia wskazuje na usługę Azure SQL przy użyciu niestandardowego rekordu CNAME lub niestandardowej nazwy DNS vanity, której sufiks nie jest rozpoznawany jako punkt końcowy usługi Azure SQL. Automatyczne zastępowanie dotyczy konkretnie usługi Azure SQL; nie jest stosowane w przypadku lokalnego serwera SQL Server, więc TNIR jest tam domyślnie włączony.

Długie opóźnienia połączenia w .NET Framework

W środowisku .NET Framework TransparentNetworkIPResolution=True (wartość domyślna) może powodować długie opóźnienia przy nawiązywaniu połączenia oraz przekroczenia limitu czasu uzgadniania połączenia przed uwierzytelnieniem, gdy docelowa nazwa DNS jest rozwiązywana na wiele adresów IP, a jeden z wcześniejszych adresów IP jest niesprawny, nieaktualny lub nieosiągalny. TNIR sekwencyjnie próbuje uzyskane adresy IP i w każdej rundzie zwiększa limit czasu dla każdej próby, aż do osiągnięcia całkowitego limitu Connect Timeout. Zazwyczaj obserwujesz nieoczekiwanie długie opóźnienie połączenia, które kończy się tym błędem:

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.

Wzór ten pojawia się w kilku topologiach:

  • Azure SQL Database, Azure SQL Managed Instance lub baza danych SQL w usłudze Microsoft Fabric. Brama Azure SQL kieruje każdą autoryzację do repliki backendu. Gdy połączenie trasowane zakończy się niepowodzeniem, TNIR ponawia próbę połączenia z trasowanym backendem bez powrotu do bramy w celu ponownego przekierowania, co zwiększa opóźnienie podczas przełączania awaryjnego backendu.
  • Lokalny serwer SQL Server za pośrednictwem detektora grupy dostępności Always On, którego nazwa DNS jest rozpoznawana jako wiele adresów IP replik. Nieaktualny wpis DNS lub niedziałający adres IP repliki są kolejno sprawdzane, zanim TNIR trafi na działającą replikę.
  • Instancje klastra awaryjnego z wielopodsieciowym nasłuchowatorem klastrowym lub inna konfiguracja, w której docelowa nazwa DNS ma wiele A/AAAA rekordów (np. runda DNS).

Aby uniknąć tego zachowania, ustaw MultiSubnetFailover=True w parametrach połączenia:

MultiSubnetFailover=True

To zalecenie działa na każdej wersji .NET i obejmuje zarówno Azure SQL, jak i lokalny SQL Server. Gdy MultiSubnetFailover=True, sterownik ignoruje TransparentNetworkIPResolution, podejmuje równoległe próby połączenia z adresami IP zwróconymi przez DNS i kończy uwierzytelnianie przy użyciu pierwszej repliki, która odpowie. Pomimo nazwy MultiSubnetFailover ma zastosowanie do każdego słuchacza, którego nazwa DNS jest rozwiązywana do wielu docelowych adresów IP, niezależnie od tego, czy adresy te znajdują się w różnych podsieciach, i jest bezpieczne w przypadku serwerów autonomicznych, których nazwa DNS jest rozwiązywana do jednego adresu IP.

Aby włączyć to ustawienie dla całego procesu bez edytowania każdego parametru połączenia, użyj przełącznika AppContext Enable MultiSubnetFailover by default.

Wyłącz TNIR za pomocą przełącznika AppContext

Aby zmienić w środowisku .NET Framework domyślną wartość parametru TransparentNetworkIPResolution z true na false, ustaw podczas uruchamiania aplikacji przełącznik AppContext Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString na true. Ten przełącznik zmienia domyślną wartość tylko wtedy, gdy TransparentNetworkIPResolution nie znajduje się w parametry połączenia; nie nadpisuje wartości jawnej.

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

Aby uzyskać więcej informacji na temat ustawiania tych właściwości, zobacz dokumentację właściwości SqlConnection.ConnectionString.

Włączanie minimalnego limitu czasu podczas logowania

Dotyczy: .NET Framework; .NET; .NET Standard

Aby zapobiec bezterminowemu oczekiwaniu podczas próby logowania, możesz ustawić przełącznik AppContext Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin na true podczas uruchamiania aplikacji:

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

Wyłącz blokowanie działania funkcji ReadAsync

Dotyczy: .NET Framework; .NET; .NET Standard

Od wersji 3.0 działa ReadAsync asynchronicznie. Poprzednie wersje uruchamiają ReadAsync synchronicznie i blokują wątek wywołujący w środowisku .NET Framework. Aby kontrolować to blokujące działanie, podczas uruchamiania aplikacji ustaw przełącznik AppContext Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking na false lub true:

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

Włącz obsługę wartości null dla rowversion

Dotyczy: .NET Framework; .NET; .NET Standard

Począwszy od wersji 3.0, gdy rowversion ma wartość null, SqlDataReader zwraca DBNull wartość zamiast pustej byte[]. Aby włączyć starsze zachowanie polegające na zwracaniu pustej wartości byte[], włącz przełącznik AppContext Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior podczas uruchamiania aplikacji.

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

Pomijanie niezabezpieczonego ostrzeżenia protokołu TLS

Dotyczy: .NET Framework; .NET; .NET Standard

(Dostępne od wersji 4.0.1)

Podczas używania Encrypt=false w parametry połączenia, konsola wysyła ostrzeżenie o zabezpieczeniu, jeśli wersja TLS jest 1.2 lub niższa. Usuń to ostrzeżenie, włączając następujący przełącznik AppContext przy starcie aplikacji:

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

Ignoruj dostarczonego partnera trybu failover serwera

Dotyczy: .NET Framework; .NET; .NET Standard

(Dostępne począwszy od wersji 5.1.8, 6.0.4 i 6.1.3)

Po przełączeniu na tryb failover, informacje o partnerze trybu failover udostępniane przez serwer są preferowane nad informacje o partnerze trybu failover zawarte w ciągu połączenia. Aby zignorować informacje o partnerze trybu failover dostarczone przez serwer i rozważyć tylko informacje o partnerze trybu failover podane w parametrach połączenia, włącz ten przełącznik AppContext podczas uruchamiania aplikacji:

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

Wymuś limit czasu bezczynności połączenia

Dotyczy: .NET Framework; .NET; .NET Standard

Począwszy od wersji 7.1.0-preview2, Connection Idle Timeout słowo kluczowe parametry połączenia konfiguruje czas bezczynności w sekundach, po czym połączenie w grupie kwalifikuje się do usunięcia (domyślnie 300; wartość 0 wyłącza wygaśnięcie bezczynności). Połączenie spełniające warunki zostaje usunięte podczas późniejszego przebiegu pobierania lub konserwacji, więc dokładny moment może się różnić w zależności od implementacji puli i częstotliwości prac konserwacyjnych. Słowo kluczowe jest egzekwowane tylko wtedy, gdy zachowanie legacyjnego limitu bezczynności jest wyłączone. Gdy przełącznik osiąga domyślną wartość true, pula zachowuje historyczne zachowanie, a słowo kluczowe nie ma wpływu.

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

Włącz pulę połączeń V2

Dotyczy: .NET Framework; .NET; .NET Standard

Począwszy od wersji 6.1, SqlClient zawiera alternatywną, eksperymentalną implementację puli połączeń (V2). Pula V1 pozostaje domyślna (przełącznik jest domyślnie ustawiony na false). Aby dołączyć do puli V2, włącz przełącznik AppContext Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2 podczas uruchamiania aplikacji.

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

Wliczaj oczekiwanie na pulę połączeń do limitu czasu połączenia

Dotyczy: .NET Framework; .NET; .NET Standard

Począwszy od wersji 7.1.0-preview2 czas oczekiwania na uzyskanie połączenia z puli może być wliczany do limitu czasu wywołania Connect Timeout, więc oczekiwanie na połączenie z puli i próba nawiązania połączenia sieciowego współdzielą jeden łączny limit czasu. Gdy przełącznik zostanie ustawiony na domyślną wartość false, operacje na puli otrzymują pełny budżet Connect Timeout, a próba nawiązania połączenia sieciowego otrzymuje dodatkowo osobny pełny budżet.

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

Przywróć starszą naprzemienność przełączania awaryjnego w przypadku błędów logowania

Dotyczy: .NET Framework; .NET; .NET Standard

Począwszy od wersji 7.1.0-preview2, podczas nawiązywania połączenia przy skonfigurowanym mechanizmie failover, SqlClient nie przełącza się już na partnera trybu failover w przypadku błędów SQL zwracanych podczas fazy logowania. Aby przywrócić dotychczasowe zachowanie alternacji, włącz przełącznik AppContext Switch.Microsoft.Data.SqlClient.UseLegacyFailoverAlternationOnLoginSqlErrors podczas uruchamiania aplikacji. Przełącznik domyślnie ma wartość false.

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

Uwzględniaj jawnie ustawioną wartość skali 0 dla parametrów vartime

Dotyczy: .NET Framework; .NET; .NET Standard

Domyślnie SqlClient wysyła skalę 7, gdy wyraźnie ustawisz skalę na 0 dla datetime2, datetimeoffsetlub time parameters. W wersji 6.0 lub nowszej ustaw Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour na false przy starcie aplikacji, aby zachować jawną skalę 0. Przełącznik domyślnie jest ustawiony na true.

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