Pooling Koneksi SQL Server (ADO.NET)
Menghubungkan 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 koneksi harus diurai, koneksi 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 koneksi. Ini berarti bahwa selama eksekusi aplikasi, banyak koneksi identik akan berulang kali dibuka dan ditutup. Untuk meminimalkan biaya membuka koneksi, ADO.NET menggunakan teknik optimasi yang disebut connection pooling.
Kumpulan koneksi mengurangi berapa kali koneksi baru harus dibuka. Pooler mempertahankan kepemilikan koneksi fisik. Ini mengelola koneksi dengan tetap hidup satu set koneksi aktif untuk setiap konfigurasi koneksi yang diberikan. Setiap kali pengguna memanggil Open koneksi, pooler mencari koneksi yang tersedia di kumpulan. Jika koneksi gabungan tersedia, ia mengembalikannya ke penelepon alih-alih membuka koneksi baru. Ketika aplikasi memanggil Close koneksi, pooler mengembalikannya ke kumpulan koneksi aktif yang dikumpulkan alih-alih menutupnya. Setelah koneksi dikembalikan ke kumpulan, koneksi siap untuk digunakan kembali pada panggilan berikutnya Open .
Hanya koneksi dengan konfigurasi yang sama yang dapat dikumpulkan. ADO.NET menyimpan beberapa pool pada saat yang sama, satu untuk setiap konfigurasi. Koneksi dipisahkan menjadi kumpulan berdasarkan string koneksi, dan dengan Windows identitas saat keamanan terintegrasi digunakan. Koneksi juga dikumpulkan berdasarkan apakah mereka terdaftar dalam transaksi. Saat menggunakan ChangePassword, SqlCredential instans memengaruhi kumpulan koneksi. Instans yang SqlCredential berbeda akan menggunakan kumpulan koneksi yang berbeda, bahkan jika ID pengguna dan kata sandinya sama.
Menggabungkan koneksi dapat secara signifikan meningkatkan kinerja dan skalabilitas aplikasi Anda. Secara default, kumpulan koneksi diaktifkan di ADO.NET. Kecuali Anda secara eksplisit menonaktifkannya, pooler mengoptimalkan koneksi saat dibuka dan ditutup dalam aplikasi Anda. Anda juga dapat menyediakan beberapa pengubah string koneksi untuk mengontrol perilaku penyatuan koneksi. Untuk informasi selengkapnya, lihat "Mengontrol Kumpulan Koneksi dengan Kata Kunci String Koneksi" nanti di topik ini.
Catatan
Ketika pengumpulan koneksi diaktifkan, dan jika kesalahan batas waktu atau kesalahan login lainnya terjadi, pengecualian akan dilemparkan dan upaya koneksi berikutnya akan gagal selama lima detik berikutnya, "periode pemblokiran". Jika aplikasi mencoba untuk terhubung 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
Ketika koneksi pertama kali dibuka, kumpulan koneksi dibuat berdasarkan algoritma pencocokan yang tepat yang mengaitkan kumpulan dengan string koneksi dalam koneksi. Setiap kumpulan koneksi dikaitkan dengan string koneksi yang berbeda. Saat koneksi baru dibuka, jika string koneksi tidak sama persis dengan kumpulan yang ada, kumpulan baru dibuat. Koneksi dikumpulkan per proses, per domain aplikasi, per string koneksi dan ketika keamanan terintegrasi digunakan, per Windows identitas. String koneksi juga harus cocok; kata kunci yang disediakan dalam urutan yang berbeda untuk koneksi yang sama akan dikumpulkan secara terpisah.
Dalam contoh C# berikut, tiga objek baru SqlConnection 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.
}
Jika Min Pool Size tidak ditentukan dalam string koneksi atau ditentukan sebagai nol, koneksi di kumpulan akan ditutup setelah periode tidak aktif. Namun, jika yang Min Pool Size ditentukan lebih besar dari nol, kumpulan koneksi tidak dihancurkan sampai AppDomain diturunkan dan proses berakhir. Pemeliharaan kolam tidak aktif atau kosong melibatkan overhead sistem minimal.
Catatan
Kumpulan dibersihkan secara otomatis ketika terjadi kesalahan fatal, seperti failover.
Menambahkan Koneksi
Kumpulan koneksi dibuat untuk setiap string koneksi unik. Saat kumpulan dibuat, beberapa objek koneksi dibuat dan ditambahkan ke kumpulan sehingga persyaratan ukuran kumpulan minimum terpenuhi. Koneksi ditambahkan ke kumpulan sesuai kebutuhan, hingga ukuran kumpulan maksimum yang ditentukan (100 adalah default). Koneksi dilepaskan kembali ke kolam ketika mereka ditutup atau dibuang.
Ketika suatu SqlConnection objek diminta, itu diperoleh dari kolam jika koneksi 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 tautan yang valid ke server.
Pooler koneksi memenuhi permintaan koneksi dengan realokasi koneksi saat dilepaskan kembali ke kolam. Jika ukuran kolam maksimum telah tercapai dan tidak ada koneksi yang dapat digunakan yang tersedia, permintaan akan diantrekan. Pooler kemudian mencoba untuk merebut kembali koneksi apa pun sampai waktu habis tercapai (defaultnya adalah 15 detik). Jika pooler tidak dapat memenuhi permintaan sebelum waktu koneksi habis, pengecualian akan dilemparkan.
Perhatian
Kami sangat menyarankan agar Anda selalu menutup koneksi ketika Anda selesai menggunakannya sehingga koneksi akan dikembalikan ke kolam renang. Anda dapat melakukan ini menggunakan metode atau Dispose metode objek, atau dengan Close membuka semua koneksi di dalam using pernyataan di C #, atau Using pernyataan di Connection 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, a DataReader, atau objek terkelola lainnya dalam Finalize metode kelas Anda. Dalam finalizer, hanya lepaskan sumber daya yang tidak dikelola yang dimiliki kelas Anda secara langsung. Jika kelas Anda tidak memiliki sumber daya yang tidak dikelola, jangan sertakan Finalize metode dalam definisi kelas Anda. Untuk informasi selengkapnya, lihat Pengumpulan Sampah.
Untuk info selengkapnya tentang peristiwa yang terkait dengan membuka dan menutup koneksi, lihat Kelas Peristiwa Login Audit dan Kelas Peristiwa Logout Audit di dokumentasi SQL Server.
Menghapus Koneksi
Pooler koneksi menghapus koneksi dari kumpulan setelah idle selama sekitar 4-8 menit, atau jika pooler mendeteksi bahwa koneksi dengan server telah terputus. Perhatikan bahwa koneksi yang terputus dapat dideteksi hanya setelah mencoba berkomunikasi dengan server. Jika koneksi ditemukan yang tidak lagi terhubung ke server, itu ditandai sebagai tidak valid. Koneksi yang tidak valid dihapus dari kumpulan koneksi hanya ketika ditutup atau direklamasi.
Jika koneksi ada ke server yang telah menghilang, koneksi ini dapat diambil dari kumpulan bahkan jika pooler koneksi belum mendeteksi koneksi yang terputus dan menandainya sebagai tidak valid. Ini terjadi karena overhead memeriksa bahwa koneksi masih berlaku akan menghilangkan manfaat memiliki pooler 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.
Membersihkan Kolam Renang
ADO.NET 2.0 memperkenalkan dua metode baru untuk membersihkan kolam: ClearAllPools dan ClearPool. ClearAllPools membersihkan kumpulan koneksi untuk penyedia tertentu, dan ClearPool membersihkan kumpulan koneksi yang terkait dengan koneksi tertentu. Jika ada koneksi yang digunakan pada saat panggilan, mereka ditandai dengan tepat. Ketika mereka ditutup, mereka dibuang bukannya dikembalikan ke kolam renang.
Dukungan Transaksi
Koneksi diambil dari kumpulan dan ditetapkan berdasarkan konteks transaksi. Kecuali Enlist=false ditentukan dalam string koneksi, kumpulan koneksi memastikan bahwa koneksi terdaftar dalam Current konteks. Ketika koneksi ditutup dan dikembalikan ke pool dengan transaksi terdaftar System.Transactions , itu disisihkan sedemikian rupa sehingga permintaan berikutnya untuk kumpulan koneksi dengan transaksi yang sama System.Transactions akan mengembalikan koneksi yang sama jika tersedia. Jika permintaan tersebut dikeluarkan, dan tidak ada koneksi gabungan yang tersedia, koneksi diambil dari bagian kolam yang tidak ditransaksikan dan didaftarkan. Jika tidak ada koneksi yang tersedia di kedua area kumpulan, koneksi baru dibuat dan didaftarkan.
Ketika koneksi ditutup, itu dilepaskan kembali ke kolam 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 melakukan atau membatalkan transaksi terdistribusi nanti.
Mengontrol Pooling Koneksi dengan Kata Kunci String Koneksi
Properti ConnectionStringSqlConnection objek mendukung pasangan kunci/nilai string koneksi yang dapat digunakan untuk menyesuaikan perilaku logika kumpulan koneksi. Untuk informasi selengkapnya, lihat ConnectionString.
Fragmentasi Kolam Renang
Fragmentasi kolam renang adalah masalah umum di banyak aplikasi Web di mana aplikasi dapat membuat sejumlah besar kolam yang tidak dibebaskan sampai proses keluar. Hal ini membuat sejumlah besar koneksi terbuka dan mengkonsumsi memori, yang mengakibatkan kinerja yang buruk.
Fragmentasi Kolam Renang Karena Keamanan Terintegrasi
Koneksi dikumpulkan sesuai dengan string koneksi ditambah identitas pengguna. Oleh karena itu, jika Anda menggunakan autentikasi dasar atau Autentikasi Windows di situs Web dan login keamanan terintegrasi, Anda mendapatkan satu kumpulan per pengguna. Meskipun ini meningkatkan kinerja permintaan database berikutnya untuk satu pengguna, pengguna tersebut tidak dapat memanfaatkan koneksi 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 Kolam Karena Banyak Database
Banyak penyedia layanan Internet meng-host beberapa situs Web pada satu server. Mereka dapat menggunakan satu database untuk mengonfirmasi login autentikasi Formulir dan kemudian membuka koneksi ke database tertentu untuk pengguna atau grup pengguna tersebut. Koneksi ke database otentikasi dikumpulkan dan digunakan oleh semua orang. Namun, ada kumpulan koneksi terpisah ke setiap database, yang meningkatkan jumlah koneksi 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 terhubung ke database terpisah untuk setiap pengguna atau grup, sambungkan ke database yang sama di server dan kemudian jalankan pernyataan Transact-SQL USE untuk diubah ke database yang diinginkan. Fragmen kode berikut menunjukkan membuat koneksi awal ke master database dan kemudian beralih ke database yang diinginkan yang ditentukan dalam databaseName variabel string.
' Assumes that command is a valid SqlCommand object and that
' connectionString connects to master.
command.Text = "USE DatabaseName"
Using connection As New SqlConnection(connectionString)
connection.Open()
command.ExecuteNonQuery()
End Using
// Assumes that command is a SqlCommand object and that
// connectionString connects to master.
command.Text = "USE DatabaseName";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
connection.Open();
command.ExecuteNonQuery();
}
Peran Aplikasi dan Pooling Koneksi
Setelah peran aplikasi SQL Server diaktifkan dengan memanggil sp_setapprole prosedur yang disimpan sistem, konteks keamanan koneksi itu tidak dapat diatur ulang. Namun, jika pooling diaktifkan, koneksi dikembalikan ke kumpulan, dan kesalahan terjadi ketika koneksi gabungan digunakan kembali. Untuk informasi selengkapnya, lihat artikel Basis Pengetahuan, "SQL kesalahan peran aplikasi dengan kumpulan sumber daya OLE DB."
Alternatif Peran Aplikasi
Kami menyarankan Anda memanfaatkan mekanisme keamanan yang dapat Anda gunakan alih-alih peran aplikasi. Untuk informasi selengkapnya, lihat Membuat Peran Aplikasi di SQL Server.