Pengalih AppContext di SqlClient

Berlaku untuk: .NET Framework .NET .NET Standard

Mengunduh ADO.NET

Kelas AppContext memungkinkan SqlClient untuk menyediakan fungsionalitas baru sambil terus mendukung pemanggil yang bergantung pada perilaku sebelumnya. Pengguna dapat menolak perubahan perilaku dengan mengatur sakelar AppContext tertentu.

SqlClient membaca dan menyimpan cache setiap switch saat pertama kali menggunakan switch tersebut. Atur switch saat startup aplikasi, sebelum Anda menggunakan tipe SqlClient apa pun. Mengganti switch setelah SqlClient menyimpan nilainya dalam cache tidak berpengaruh.

Aktifkan MultiSubnetFailover secara default

Berlaku untuk: .NET Framework; .NET; .NET Standard

(Tersedia dimulai dengan versi 7.0)

Untuk mengatur MultiSubnetFailover=true secara global tanpa mengubah string koneksi individual, atur switch Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault AppContext ke true saat aplikasi dimulai:

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

Anda juga dapat mengaktifkan sakelar ini di App.Config:

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

Saat diaktifkan, semua koneksi berperilaku seolah-olah MultiSubnetFailover=true diatur dalam string koneksi. Sakelar ini dinonaktifkan pada pengaturan awal.

Mengaktifkan multipleksing paket untuk pembacaan asinkron

Berlaku untuk: .NET Framework; .NET; .NET Standard

(Tersedia dimulai dengan versi 7.0)

Multipleks paket meningkatkan performa untuk operasi baca asinkron besar seperti ExecuteReaderAsync dengan kumpulan hasil besar, skenario streaming, atau pengambilan data massal. Fitur ini dikendalikan oleh dua pengaturan AppContext pilihan. Mengatur kedua sakelar ke false mengaktifkan jalur pemrosesan asinkron baru:

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

Secara default, kedua sakelar adalah true, yang mempertahankan perilaku yang ada (kompatibel).

Mengaktifkan perilaku pemotongan desimal

Berlaku untuk: .NET Framework; .NET; .NET Standard

Dimulai dengan Microsoft.Data.SqlClient 2.0, data desimal dibulatkan secara default, seperti yang dilakukan oleh SQL Server. Untuk mengaktifkan perilaku pemotongan sebelumnya, Anda dapat mengatur switch AppContext Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal ke true saat aplikasi dimulai:

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

Mengaktifkan jaringan terkelola pada Windows

Berlaku untuk: .NET; .NET Standard

(Tersedia dimulai dengan versi 2.0)

Di Windows, SqlClient menggunakan implementasi asli antarmuka jaringan SNI secara default. Untuk mengaktifkan penggunaan implementasi SNI terkelola, atur switch Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows AppContext ke true saat aplikasi dimulai:

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

Sakelar ini mengalihkan perilaku driver untuk menggunakan implementasi jaringan terkelola di proyek .NET Core 2.1+ dan .NET Standard 2.0+ di Windows, menghilangkan semua dependensi pada pustaka asli untuk pustaka Microsoft.Data.SqlClient. Ini hanya untuk tujuan pengujian dan penelusuran kesalahan.

Catatan

Ada beberapa perbedaan yang diketahui jika dibandingkan dengan implementasi asli. Misalnya, implementasi yang dikelola tidak mendukung Autentikasi Windows non-domain.

Nonaktifkan Resolusi IP Jaringan Transparan

Berlaku untuk: .NET Framework

Resolusi IP Jaringan Transparan (TNIR) adalah revisi dari fitur MultiSubnetFailover yang sudah ada. TNIR memengaruhi urutan koneksi driver dalam kasus di mana IP pertama yang diresolusikan dari nama host tidak merespons, dan terdapat beberapa IP yang terkait dengan nama host. Kombinasi TransparentNetworkIPResolution dan MultiSubnetFailover memilih urutan koneksi:

Resolusi IP Jaringan Transparan MultiSubnetFailover Urutan koneksi
Benar Benar TransparentNetworkIPResolution diabaikan. Driver mencoba alamat IP yang diselesaikan DNS secara paralel dan menyelesaikan autentikasi dengan responder pertama.
Benar False Driver menjalankan beberapa ronde koneksi pada alamat IP hasil resolusi DNS, dengan minimum 500 milidetik pada percobaan pertama dan batas waktu tiap percobaan yang makin besar secara bertahap, hingga koneksi berhasil atau Connect Timeout keseluruhan tercapai.
False Benar Driver mencoba alamat IP yang diselesaikan DNS secara paralel dan menyelesaikan autentikasi dengan responder pertama.
False False Driver mencoba setiap alamat IP hasil resolusi DNS secara berurutan hingga salah satunya berhasil atau hingga Connect Timeout tercapai.

TransparentNetworkIPResolutiondiaktifkan secara default pada .NET Framework, dan MultiSubnetFailover dinonaktifkan secara default. Pada .NET 5 dan versi yang lebih baru, TransparentNetworkIPResolution tidak dikenali sebagai kata kunci string koneksi, dan menetapkannya (dengan nilai apa pun) akan memunculkan ArgumentException (KeywordNotSupported). Versi tersebut hanya mematuhi MultiSubnetFailover. Bagian selebihnya dari bagian ini (penggantian otomatis, mode kegagalan dalam peringatan berikut ini, dan pengalih AppContext) berlaku untuk .NET Framework.

Tip

Atur MultiSubnetFailover=True pada setiap string koneksi, terlepas dari versi .NET atau apakah targetnya Azure SQL atau SQL Server lokal. MultiSubnetFailover=True memilih jalur kode koneksi paralel yang dengan cepat menemukan replika pertama yang responsif. Pada .NET Framework, ini juga melewati loop percobaan ulang berurutan per-IP milik TNIR, yang merupakan penyebab umum penundaan koneksi yang lama dan batas waktu handshake praautentikasi.

Di .NET Framework, saat TransparentNetworkIPResolution tidak ditentukan dalam string koneksi, driver secara otomatis menonaktifkan TNIR ketika sumber data adalah endpoint Azure SQL yang dikenali, saat kunci Authentication diatur ke metode Microsoft Entra ID apa pun (Direktori Aktif Password, Direktori Aktif Integrated, Direktori Aktif Interactive, Direktori Aktif Service Principal, Direktori Aktif Device Code Flow, Direktori Aktif Managed Identity, Direktori Aktif MSI, Direktori Aktif Default, atau Direktori Aktif Workload Identity), atau saat properti SqlConnection.AccessToken diatur. Untuk akhiran endpoint yang dikenali oleh driver, lihat entri TransparentNetworkIPResolution di SqlConnection.ConnectionString.

Nilai eksplisit TransparentNetworkIPResolution melewati perilaku otomatis ini: True mengaktifkan TNIR, dan False menonaktifkan TNIR tanpa syarat. Untuk mengembalikan perilaku otomatis, hapus kata kunci dari string koneksi. Penggantian otomatis juga tidak berlaku ketika string koneksi mengarah ke Azure SQL melalui CNAME kustom atau nama DNS vanity yang sufiksnya tidak dikenali sebagai endpoint Azure SQL. Override otomatis secara khusus ditujukan untuk Azure SQL; override ini tidak berlaku untuk SQL Server on-premises, sehingga TNIR aktif secara default di sana.

Penundaan koneksi yang panjang di .NET Framework

Di .NET Framework, TransparentNetworkIPResolution=True (default) dapat menyebabkan penundaan koneksi yang lama dan timeout handshake pra-otentikasi setiap kali nama DNS target beralih ke beberapa IP dan salah satu IP sebelumnya tidak sehat, basi, atau tidak dapat dijangkau. TNIR mencoba alamat-alamat IP hasil resolusi secara berurutan dan meningkatkan batas waktu untuk setiap percobaan pada setiap putaran hingga Connect Timeout total tercapai. Anda biasanya melihat jeda koneksi yang tidak terduga lama yang berakhir dengan kesalahan ini:

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.

Pola ini muncul dalam beberapa topologi:

  • Azure SQL Database, Azure SQL Managed Instance, atau database SQL di Microsoft Fabric. Gateway Azure SQL mengarahkan setiap autentikasi ke replika backend. Ketika koneksi yang dirutekan gagal, TNIR mencoba kembali backend yang dirutekan tanpa kembali ke gateway untuk dirutekan ulang, yang menambah durasi penundaan selama failover backend.
  • SQL Server lokal (on-premises) di belakang listener grup ketersediaan Always On yang nama DNS-nya diterjemahkan menjadi beberapa alamat IP replika. Entri DNS yang sudah lama atau IP replika yang tidak sehat dicoba secara berurutan sebelum TNIR mencapai replika yang berfungsi.
  • Instans kluster failover dengan pendengar kluster multisubnet, atau konfigurasi lain apa pun yang nama DNS targetnya memiliki beberapa rekaman A/AAAA (seperti DNS round-robin).

Untuk menghindari perilaku ini, atur MultiSubnetFailover=True di string koneksi:

MultiSubnetFailover=True

Rekomendasi ini berlaku di setiap versi .NET dan mencakup baik Azure SQL maupun SQL Server lokal. Ketika MultiSubnetFailover=True, driver mengabaikan TransparentNetworkIPResolution, mencoba alamat IP hasil resolusi DNS secara paralel, dan menyelesaikan autentikasi dengan replika pertama yang merespons. Meskipun namanya demikian, MultiSubnetFailover berlaku untuk listener apa pun yang nama DNS-nya diterjemahkan menjadi beberapa alamat IP target, terlepas dari apakah alamat-alamat IP tersebut berada di subnet yang berbeda, dan aman untuk server mandiri yang nama DNS-nya diterjemahkan menjadi satu alamat IP.

Untuk kontrol proses secara menyeluruh tanpa mengedit setiap string koneksi, gunakan switch Enable MultiSubnetFailover by default AppContext.

Nonaktifkan TNIR menggunakan pengalih AppContext

Untuk membalik nilai default TransparentNetworkIPResolution dari true menjadi false pada .NET Framework, atur switch AppContext Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString ke true saat startup aplikasi. Pengalih ini hanya mengubah nilai default saat TransparentNetworkIPResolution tidak ada dalam string koneksi; pengalih ini tidak mengganti nilai yang ditentukan secara eksplisit.

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

Untuk informasi selengkapnya tentang mengatur properti ini, lihat dokumentasi untuk SqlConnection.ConnectionString Property.

Nonaktifkan waktu tunggu minimum saat login

Berlaku untuk: .NET Framework; .NET; .NET Standard

Secara default, SqlClient memberlakukan minimum satu detik saat menghitung waktu yang tersedia untuk percobaan login. Perilaku ini mencegah upaya login menunggu tanpa batas waktu ketika timeout yang dihitung dibulatkan ke nol.

Untuk mengembalikan perilaku lama, atur switch Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin AppContext ke false saat aplikasi dimulai:

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

Menonaktifkan perilaku pemblokiran ReadAsync

Berlaku untuk: .NET Framework; .NET; .NET Standard

Mulai dari versi 3.0, ReadAsync berjalan secara asinkron. Versi sebelumnya berjalan ReadAsync secara sinkron dan memblokir thread pemanggil di .NET Framework. Untuk mengontrol perilaku pemblokiran ini, atur switch AppContext Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking ke true atau false saat aplikasi dimulai:

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

Aktifkan perilaku rowversion null

Berlaku untuk: .NET Framework; .NET; .NET Standard

Mulai dari versi 3.0, ketika rowversion memiliki nilai null, SqlDataReader mengembalikan DBNull nilai menggantikan byte[]kosong. Untuk mengaktifkan perilaku lama yang mengembalikan byte[] kosong, aktifkan switch AppContext Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior saat aplikasi dijalankan.

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

Menghilangkan peringatan tentang TLS yang tidak aman

Berlaku untuk: .NET Framework; .NET; .NET Standard

(Tersedia dimulai dengan versi 4.0.1)

Saat digunakan Encrypt=false dalam string koneksi, konsol akan mengeluarkan peringatan keamanan jika versi TLS adalah 1.2 atau lebih rendah. Hapus peringatan ini dengan mengaktifkan saklar AppContext berikut saat aplikasi dimulai:

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

Abaikan Mitra Failover yang Disediakan Server

Berlaku untuk: .NET Framework; .NET; .NET Standard

(Tersedia mulai dari versi 5.1.8, 6.0.4, dan 6.1.3)

Setelah failover, informasi mitra failover yang disediakan oleh server lebih diutamakan daripada informasi mitra failover yang tercantum dalam string koneksi. Untuk mengabaikan informasi mitra failover yang disediakan oleh server dan hanya mempertimbangkan informasi mitra failover yang disediakan dalam string koneksi, aktifkan pengalihan AppContext ini pada startup aplikasi:

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

Terapkan batas waktu idle koneksi

Berlaku untuk: .NET Framework; .NET; .NET Standard

Mulai versi 7.1.0, Connection Idle Timeout kata kunci string koneksi dan SqlConnectionStringBuilder.IdleTimeout properti mengonfigurasi pemeriksaan kedaluwarsa idle dan pembersihan latar belakang untuk koneksi pooled. Defaultnya adalah 300 detik. Nilai negatif menghasilkan ArgumentException error.

Pengaturan switch dan string koneksi memengaruhi setiap implementasi pool secara berbeda:

  • V1 pool. Ketika switch disetel ke true, V1 menggunakan interval pembersihan acak historis setiap dua hingga empat menit dan menutup koneksi idle tanpa memandang Connection Idle Timeout. Ketika switch adalah false dan Connection Idle Timeout bernilai bukan nol, V1 menggunakan setengah timeout yang dikonfigurasi sebagai cadence pembersihan dan mengeluarkan koneksi idle setelah satu atau dua siklus pembersihan. Ketika saklar adalah false dan Connection Idle Timeout=0, V1 menonaktifkan penghapusan koneksi idle tetapi melanjutkan pemeliharaan ukuran pool minimum pada interval acak historis dua hingga empat menit.
  • Pool V2. Ketika switch adalah true, V2 tidak melakukan pemeriksaan usia idle per koneksi, tetapi Connection Idle Timeout yang bukan nol mengaktifkan dan mengonfigurasi pemangkasan latar belakang. Ketika switch bernilai false dan Connection Idle Timeout tidak nol, V2 melakukan pemeriksaan usia idle per koneksi dan mengonfigurasi pemangkasan latar belakang dari timeout. Ketika switch diatur ke false atau Connection Idle Timeout=0, V2 tidak melakukan pemeriksaan usia idle per koneksi atau pemangkasan latar belakang. V2 tidak melakukan pemangkasan latar belakang ketika Min Pool Size lebih besar dari atau sama dengan Max Pool Size.
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseLegacyIdleTimeoutBehavior", false);

Untuk contoh konfigurasi, lihat Batasi waktu idle koneksi.

Aktifkan pool koneksi V2

Berlaku untuk: .NET Framework; .NET; .NET Standard

Mulai versi 7.1, SqlClient menyertakan implementasi pool koneksi alternatif (V2). Pool V1 tetap menjadi default, dan switch secara default menggunakan false.

Untuk mengaktifkan V2, aktifkan switch AppContext Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2 saat aplikasi dimulai:

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

Kontrol pooling string koneksi berlaku untuk kedua implementasi tersebut. Untuk informasi lebih lanjut, lihat SQL Server connection pooling.

Gunakan satu waktu tunggu koneksi untuk menunggu pool dan koneksi jaringan

Berlaku untuk: .NET Framework; .NET; .NET Standard

Mulai versi 7.1.0, waktu menunggu koneksi dari pool dapat dihitung sebagai bagian dari batas waktu pemanggil Connect Timeout, sehingga pool wait dan upaya koneksi jaringan berbagi satu timeout keseluruhan. Aktifkan Switch.Microsoft.Data.SqlClient.UseOverallConnectTimeoutForPoolWait untuk menggunakan timeout keseluruhan dengan implementasi pool koneksi manapun:

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

Saklar secara bawaan disetel ke false. Default ini mempertahankan perilaku connect-timeout lama, di mana operasi pool menerima connect-timeout penuh Connect Timeout dan upaya koneksi jaringan menerima timeout penuh lainnya. Akibatnya, Open atau OpenAsync dapat memakan waktu lebih lama daripada Connect Timeout yang dikonfigurasi.

Kembalikan ke pergantian failover lama saat terjadi kesalahan login

Berlaku untuk: .NET Framework; .NET; .NET Standard

Mulai versi 7.1.0, saat terhubung dengan konfigurasi failover, SqlClient tidak lagi beralih ke mitra failover untuk kesalahan SQL yang dikembalikan selama fase login. Untuk kembali ke perilaku alternasi lama, aktifkan sakelar AppContext Switch.Microsoft.Data.SqlClient.UseLegacyFailoverAlternationOnLoginSqlErrors saat aplikasi dijalankan. Saklar secara bawaan disetel ke false.

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

Hormati skala nol eksplisit pada parameter vartime

Berlaku untuk: .NET Framework; .NET; .NET Standard

Secara default, SqlClient mengirimkan skala 7 ketika Anda secara eksplisit mengatur skala ke 0 untuk parameter datetime2, datetimeoffset, atau time . Pada versi 6.0 atau lebih baru, atur Switch.Microsoft.Data.SqlClient.LegacyVarTimeZeroScaleBehaviour ke false saat aplikasi startup untuk mempertahankan skala eksplisit 0. Saklar secara bawaan disetel ke true.

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