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).

Aktifkan ekstensi fitur Agen Pengguna

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

(Tersedia dimulai dengan versi 7.0)

Ketika sakelar AppContext Switch.Microsoft.Data.SqlClient.EnableUserAgent diaktifkan, driver mengirimkan detail user-agent ke server sebagai bagian dari proses koneksi. Informasi ini membantu pemecahan masalah dan mengukur penggunaan driver berdasarkan versi dan sistem operasi. Sakelar ini dinonaktifkan pada pengaturan awal. Untuk mengaktifkannya, atur sakelar AppContext ke true saat pengaktifan aplikasi:

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

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.

Aktifkan batas waktu minimum selama masuk

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

Untuk mencegah upaya login menunggu tanpa batas waktu, Anda dapat mengatur switch Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin AppContext ke true 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-preview2, Connection Idle Timeout kata kunci string koneksi mengonfigurasi durasi idle dalam detik, setelah itu koneksi yang digabungkan menjadi memenuhi syarat untuk pengusiran (default 300; nilai 0 menonaktifkan masa kedaluwarsa idle). Koneksi yang memenuhi syarat akan dibuang pada pengambilan berikutnya atau pada siklus pemeliharaan, sehingga waktu pastinya dapat berbeda-beda tergantung pada implementasi pool dan frekuensi pemeliharaan. Kata kunci hanya diberlakukan ketika perilaku batas waktu diam lama dinonaktifkan. Dengan sakelar pada nilai default true, pool mempertahankan perilaku historis dan kata kunci tersebut tidak berpengaruh.

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

Aktifkan pool koneksi V2

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

Mulai versi 6.1, SqlClient menyertakan implementasi pool koneksi eksperimental alternatif (V2). Pool V1 tetap menjadi default (switch secara default ke false). Untuk ikut serta dalam pool V2, aktifkan sakelar AppContext Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2 saat aplikasi dimulai.

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

Hitung waktu tunggu pool sebagai bagian dari batas waktu koneksi

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

Mulai dari versi 7.1.0-preview2, waktu yang dihabiskan untuk menunggu koneksi dari pool dapat diperhitungkan ke dalam batas waktu pemanggil Connect Timeout, sehingga waktu tunggu pool dan upaya koneksi jaringan berbagi satu batas waktu keseluruhan. Ketika switch diatur ke nilai default false, operasi pada pool menerima Connect Timeout penuh, dan upaya koneksi jaringan menerima anggaran penuh tambahan.

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

Kembalikan ke pergantian failover lama saat terjadi kesalahan login

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

Mulai dari versi 7.1.0-preview2, saat terhubung dengan konfigurasi failover, SqlClient tidak lagi bergantian dengan 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