Pengumpulan koneksi SQL Server (ADO.NET)
Menyambungkan ke server database biasanya terdiri dari beberapa langkah yang memakan waktu. Saluran fisik seperti soket atau pipa bernama harus dibuat, jabat tangan awal dengan server harus terjadi, informasi string sambungan harus diurai, sambungan harus diautentikasi oleh server, pemeriksaan harus dijalankan untuk mendaftar dalam transaksi saat ini, dan sebagainya.
Dalam praktiknya, sebagian besar aplikasi hanya menggunakan satu atau beberapa konfigurasi berbeda untuk sambungan. Ini berarti bahwa selama eksekusi aplikasi, banyak sambungan identik akan dibuka dan ditutup berulang kali. Untuk meminimalkan biaya pembukaan sambungan, ADO.NET menggunakan teknik pengoptimalan yang disebut pengumpulan sambungan.
Pengumpulan sambungan mengurangi berapa kali sambungan baru harus dibuka. Pengumpul mempertahankan kepemilikan sambungan fisik. Pengumpul mengelola sambungan dengan menjaga sekumpulan sambungan aktif tetap hidup untuk setiap konfigurasi sambungan yang diberikan. Setiap kali pengguna memanggil Open
sambungan, pengumpul mencari koneksi yang tersedia di kumpulan. Jika sambungan gabungan tersedia, sambungan itu kembali ke pemanggil alih-alih membuka koneksi baru. Ketika aplikasi memanggil Close
sambungan, pengumpul mengembalikannya ke kumpulan sambungan aktif, bukan menutupnya. Setelah sambungan dikembalikan ke kumpulan, sambungan siap untuk digunakan kembali pada Open
panggilan berikutnya.
Hanya sambungan dengan konfigurasi yang sama yang dapat dikumpulkan. ADO.NET menyimpan beberapa kumpulan secara bersamaan, satu untuk setiap konfigurasi. Sambungan dipisahkan menjadi kumpulan berdasarkan string sambungan, dan oleh identitas Windows saat keamanan terintegrasi digunakan. Sambungan juga dikumpulkan berdasarkan apakah mereka terdaftar dalam transaksi. Saat menggunakan ChangePassword, SqlCredential instans memengaruhi kumpulan sambungan. Instans yang berbeda SqlCredential akan menggunakan kumpulan sambungan yang berbeda, bahkan jika ID pengguna dan kata sandinya sama.
Mengumpulkan sambungan dapat secara signifikan meningkatkan performa dan skalabilitas aplikasi Anda. Secara default, pengumpulan sambungan diaktifkan di ADO.NET. Kecuali Anda secara eksplisit menonaktifkannya, pengumpul mengoptimalkan sambungan saat dibuka dan ditutup di aplikasi Anda. Anda juga dapat menyediakan beberapa pengubah string koneksi untuk mengontrol perilaku pengumpulan sambungan. Untuk informasi selengkapnya, lihat "Mengontrol Kumpulan Sambungan dengan Kata Kunci String Koneksi" nanti dalam topik ini.
Catatan
Ketika pengumpulan sambungan diaktifkan, dan jika kesalahan waktu habis atau kesalahan masuk lainnya terjadi, pengecualian akan dilemparkan dan upaya sambungan berikutnya akan gagal selama lima detik berikutnya, "periode pemblokiran". Jika aplikasi mencoba tersambung dalam periode pemblokiran, pengecualian pertama akan dilemparkan lagi. Kegagalan berikutnya setelah periode pemblokiran berakhir akan mengakibatkan periode pemblokiran baru yang dua kali lebih lama dari periode pemblokiran sebelumnya, hingga maksimum satu menit.
Pembuatan dan penugasan kumpulan
Saat sambungan pertama kali dibuka, kumpulan sambungan dibuat berdasarkan algoritma pencocokan yang tepat yang mengaitkan kumpulan dengan string koneksi dalam sambungan. Setiap kumpulan sambungan dikaitkan dengan string koneksi yang berbeda. Saat sambungan baru dibuka, jika string koneksi tidak sama persis dengan kumpulan yang ada, kumpulan baru dibuat. Sambungan dikumpulkan per proses, per domain aplikasi, per string koneksi dan saat keamanan terintegrasi digunakan, per identitas Windows. String koneksi juga harus sama persis; kata kunci yang disediakan dalam urutan yang berbeda untuk sambungan yang sama akan dikumpulkan secara terpisah.
Dalam contoh C# berikut, tiga SqlConnection objek baru dibuat, tetapi hanya dua kumpulan koneksi yang diperlukan untuk mengelolanya. Perhatikan bahwa string koneksi pertama dan kedua berbeda dengan nilai yang ditetapkan untuk Initial Catalog
.
using (SqlConnection connection = new SqlConnection(
"Integrated Security=SSPI;Initial Catalog=Northwind"))
{
connection.Open();
// Pool A is created.
}
using (SqlConnection connection = new SqlConnection(
"Integrated Security=SSPI;Initial Catalog=pubs"))
{
connection.Open();
// Pool B is created because the connection strings differ.
}
using (SqlConnection connection = new SqlConnection(
"Integrated Security=SSPI;Initial Catalog=Northwind"))
{
connection.Open();
// The connection string matches pool A.
}
Penting
Microsoft menyarankan agar Anda menggunakan alur autentikasi paling aman yang tersedia. Jika Anda menyambungkan ke Azure SQL, Identitas Terkelola untuk sumber daya Azure adalah metode autentikasi yang direkomendasikan.
Jika Min Pool Size
tidak ditentukan dalam string koneksi atau ditentukan sebagai nol, sambungan di kumpulan akan ditutup setelah periode tidak aktif. Namun, jika yang ditentukan Min Pool Size
lebih besar dari nol, kumpulan sambungan tidak dihancurkan sampai AppDomain
dibongkar dan proses berakhir. Pemeliharaan kumpulan yang tidak aktif atau kosong melibatkan overhead sistem minimal.
Catatan
Kumpulan secara otomatis dibersihkan ketika terjadi kesalahan fatal, seperti failover.
Menambahkan koneksi
Kumpulan sambungan dibuat untuk setiap string koneksi unik. Saat kumpulan dibuat, beberapa objek koneksi dibuat dan ditambahkan ke kumpulan sehingga persyaratan ukuran kumpulan minimum terpenuhi. Sambungan ditambahkan ke kumpulan sesuai kebutuhan, hingga ukuran kumpulan maksimum yang ditentukan (100 adalah default). Koneksi dilepaskan kembali ke kumpulan ketika ditutup atau dibuang.
Ketika SqlConnection objek diminta, objek diperoleh dari kumpulan jika sambungan yang dapat digunakan tersedia. Agar dapat digunakan, koneksi harus tidak digunakan, memiliki konteks transaksi yang cocok atau tidak terkait dengan konteks transaksi apa pun, dan memiliki link yang valid ke server.
Pengumpul sambungan memenuhi permintaan sambungan dengan merealokasi sambungan saat dilepaskan kembali ke kumpulan. Jika ukuran kumpulan maksimum telah tercapai dan tidak ada sambungan yang dapat digunakan yang tersedia, permintaan akan diantrekan. Pengumpul kemudian mencoba untuk mengklaim kembali sambungan apa pun sampai waktu habis tercapai (defaultnya adalah 15 detik). Jika pengumpul tidak dapat memenuhi permintaan sebelum waktu sambungan habis, pengecualian akan dilemparkan.
Perhatian
Kami sangat menyarankan agar Anda selalu menutup koneksi ketika Anda selesai menggunakannya sehingga koneksi akan dikembalikan ke kumpulan. Anda dapat melakukan ini menggunakan Close
atau Dispose
metode dari Connection
objek, atau dengan membuka semua sambungan di dalam using
pernyataan di C#, atau Using
pernyataan dalam Visual Basic. Koneksi yang tidak ditutup secara eksplisit mungkin tidak ditambahkan atau dikembalikan ke kumpulan. Untuk informasi selengkapnya, lihat menggunakan pernyataan atau Cara: Membuang Sumber Daya Sistem untuk Visual Basic.
Catatan
Jangan memanggil Close
atau Dispose
pada Connection
, DataReader
, atau objek terkelola lainnya dalam metode Finalize
kelas Anda. Di penyelesai, hanya merilis sumber daya yang tidak dikelola yang kelas Anda miliki secara langsung. Jika kelas Anda tidak memiliki sumber daya yang tidak dikelola, jangan sertakan metode Finalize
dalam definisi kelas Anda. Untuk informasi selengkapnya, lihat Pengumpulan Sampah.
Untuk informasi selengkapnya tentang peristiwa yang terkait dengan sambungan pembukaan dan penutupan, lihat Kelas Peristiwa Masuk Audit dan Kelas Peristiwa Keluar Audit dalam dokumentasi SQL Server.
Hapus koneksi
Pengumpul sambungan menghapus sambungan dari kumpulan setelah diam selama sekitar 4-8 menit, atau jika pengumpul mendeteksi bahwa sambungan dengan server telah terputus. Perhatikan bahwa sambungan terputus hanya dapat dideteksi setelah mencoba berkomunikasi dengan server. Jika ditemukan sambungan yang tidak lagi tersambung ke server, sambungan ditandai sebagai tidak valid. Sambungan yang tidak valid dihapus dari kumpulan sambungan hanya ketika ditutup atau diklaim kembali.
Jika ada sambungan ke server yang telah menghilang, sambungan ini dapat diambil dari kumpulan meskipun pengumpul sambungan belum mendeteksi sambungan terputus dan menandainya sebagai tidak valid. Ini terjadi karena overhead pemeriksaan bahwa koneksi masih valid akan menghilangkan manfaat memiliki pengumpul dengan menyebabkan perjalanan pulang pergi lain ke server terjadi. Ketika ini terjadi, upaya pertama untuk menggunakan koneksi akan mendeteksi bahwa koneksi telah terputus, dan pengecualian dilemparkan.
Bersihkan kumpulan
ADO.NET 2.0 memperkenalkan dua metode baru untuk membersihkan kumpulan: ClearAllPools dan ClearPool. ClearAllPools
menghapus kumpulan sambungan untuk penyedia tertentu, dan ClearPool
menghapus kumpulan sambungan yang terkait dengan sambungan tertentu. Jika ada sambungan yang digunakan pada saat panggilan, sambungan ditandai dengan tepat. Ketika ditutup, mereka dibuang alih-alih dikembalikan ke kumpulan.
Dukungan transaksi
Koneksi diambil dari kumpulan dan ditetapkan berdasarkan konteks transaksi. Kecuali Enlist=false
ditentukan dalam string koneksi, kumpulan sambungan memastikan bahwa sambungan terdaftar dalam konteks Current. Ketika sambungan ditutup dan dikembalikan ke kumpulan dengan transaksi terdaftar System.Transactions
, disisihkan sedemikian rupa sehingga permintaan berikutnya untuk kumpulan sambungan itu dengan transaksi yang sama System.Transactions
akan mengembalikan koneksi yang sama jika tersedia. Jika permintaan seperti itu dikeluarkan, dan tidak ada sambungan terkumpul yang tersedia, sambungan diambil dari bagian kumpulan yang tidak ditransaksikan dan terdaftar. Jika tidak ada sambungan yang tersedia di salah satu area kumpulan, sambungan baru dibuat dan terdaftar.
Ketika koneksi ditutup, koneksi dilepaskan kembali ke kumpulan dan ke subdivisi yang sesuai berdasarkan konteks transaksinya. Oleh karena itu, Anda dapat menutup koneksi tanpa menghasilkan kesalahan, meskipun transaksi terdistribusi masih tertunda. Ini memungkinkan Anda untuk menerapkan atau membatalkan transaksi terdistribusi nanti.
Mengontrol pengumpulan koneksi dengan kata kunci string koneksi
Properti ConnectionString
dari objek SqlConnection mendukung pasangan kunci/nilai string koneksi yang dapat digunakan untuk menyesuaikan perilaku logika penyatuan sambungan. Untuk informasi selengkapnya, lihat ConnectionString .
Fragmentasi kumpulan
Fragmentasi kumpulan adalah masalah umum di banyak aplikasi Web di mana aplikasi dapat membuat sejumlah besar kumpulan yang tidak dibebaskan sampai proses keluar. Ini membuat sejumlah besar sambungan terbuka dan mengonsumsi memori, yang menghasilkan performa yang buruk.
Fragmentasi kumpulan karena keamanan terintegrasi
Sambungan dikumpulkan sesuai dengan string koneksi ditambah identitas pengguna. Oleh karena itu, jika Anda menggunakan Autentikasi Dasar atau Autentikasi Windows di situs Web dan masuk keamanan terintegrasi, Anda mendapatkan satu kumpulan per pengguna. Meskipun ini meningkatkan performa permintaan database berikutnya untuk satu pengguna, pengguna tersebut tidak dapat memanfaatkan sambungan yang dibuat oleh pengguna lain. Ini juga menghasilkan setidaknya satu koneksi per pengguna ke server database. Ini adalah efek samping dari arsitektur aplikasi Web tertentu yang harus ditimbang pengembang terhadap persyaratan keamanan dan audit.
Fragmentasi kumpulan karena banyak database
Banyak penyedia layanan Internet meng-hosting beberapa situs Web pada satu server. Mereka dapat menggunakan database tunggal untuk mengonfirmasi masuk autentikasi Formulir lalu membuka sambungan ke database tertentu untuk pengguna atau grup pengguna tersebut. Sambungan ke database autentikasi dikumpulkan dan digunakan oleh semua orang. Namun, ada kumpulan sambungan terpisah ke setiap database, yang meningkatkan jumlah sambungan ke server.
Ini juga merupakan efek samping dari desain aplikasi. Ada cara yang relatif sederhana untuk menghindari efek samping ini tanpa mengorbankan keamanan saat Anda terhubung ke SQL Server. Alih-alih menyambungkan ke database terpisah untuk setiap pengguna atau grup, sambungkan ke database yang sama di server lalu jalankan pernyataan Transact-SQL USE untuk mengubah ke database yang diinginkan. Fragmen kode berikut menunjukkan pembuatan sambungan awal ke database master
lalu beralih ke database yang diinginkan yang ditentukan dalam variabel string databaseName
.
' Assumes that command is a SqlCommand object.
command.Text = "USE DatabaseName"
Using connection As New SqlConnection(connectionString)
connection.Open()
command.ExecuteNonQuery()
End Using
// Assumes that command is a SqlCommand object.
command.Text = "USE DatabaseName";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
connection.Open();
command.ExecuteNonQuery();
}
Peran aplikasi dan pengumpulan koneksi
Setelah peran aplikasi SQL Server diaktifkan dengan memanggil sp_setapprole
prosedur tersimpan sistem, konteks keamanan sambungan tersebut tidak dapat direset. Namun, jika pengumpulan diaktifkan, sambungan dikembalikan ke kumpulan, dan kesalahan terjadi saat sambungan terkumpul digunakan kembali.