Seberapa buruk tidak Buang () SqlConnections?

14

Secara pribadi, saya keluar dalam sarang jika saya tidak meletakkan objek ADO yang mengimplementasikan IDisposable dalam menggunakan pernyataan. Tetapi pada kontrak saya saat ini, saya telah menemukan bahwa kerangka kerja perusahaan mereka "kode penyedia akses data" tidak 1) menerapkan IDisposable dan 2) panggilan Buang () pada apa pun yang digunakannya, pada titik mana pun, selamanya. Pengguna telah banyak mengeluh tentang masalah kinerja dalam aplikasi Winforms yang banyak menggunakan kerangka kerja ini untuk akses data, dan meskipun ada BANYAK masalah lain dalam kode yang bisa mengenai kinerja, yang satu ini hanya menjerit pada saya dan lebih buah gantung rendah dibanding yang lain.

Jadi, di luar mengatakan sesuatu seperti "Buang ada karena suatu alasan, gunakan itu," apa yang bisa saya katakan kepada orang-orang ini untuk meyakinkan mereka bahwa ini benar-benar buruk?

AJ Johnson
sumber
5
Heh .. tebakan saya adalah, pada titik tertentu, meyakinkan tidak akan diperlukan :)
dr Hannibal Lecter

Jawaban:

6

Saya akan mengatakan hal terbaik yang dapat Anda lakukan adalah mengarahkan mereka ke Pola dan Praktik Microsoft di Dispose() sini . Biarkan mereka melihat konsekuensi penuh dari tidak menggunakan alat ini tepat di depan mereka.

Jesse C. Slicer
sumber
1
Seandainya saja saya dapat menemukan versi yang tidak meneriakkan "ini adalah konten yang sudah pensiun" di bagian atas.
AJ Johnson
Kau tahu, mataku hanya menutupi itu. Tetapi sekarang setelah membacanya dengan cermat, saya bertanya-tanya teknologi apa yang mungkin "masih digunakan" orang yang pensiun dari halaman itu. Mungkin CAS?
Jesse C. Slicer
Memindai lebih dekat, sebagian besar dari ini masih relevan bagi saya. Tidak yakin mengapa itu ditandai sudah pensiun.
AJ Johnson
10

Jika Anda tidak memanggil metode Buang pada Koneksi SQL, ketika Anda selesai menggunakannya, koneksi itu TIDAK akan kembali ke kumpulan koneksi.

Jika Anda mengalami masalah kinerja, tebakan saya adalah bahwa koneksi maksimum dibuka pada database Anda. DBA dapat dengan mudah mengkonfirmasi ini.

Praktik Terbaik Microsoft menghimbau Anda untuk menempatkan kode koneksi Anda di dalam pernyataan Menggunakan, memastikan koneksi dibuang dan bahwa koneksi dikembalikan kembali ke kolam.

Walter
sumber
Memanggil Closecukup untuk melepaskan kembali ke kolam koneksi. Pertanyaannya tidak menyatakan bahwa Closetidak digunakan secara eksplisit .
user2864740
9

Kumpulan koneksi database terbatas dalam ukuran, dan jika diisi, koneksi baru akan menunggu koneksi lama dirilis. Jika Anda tidak membuangnya segera setelah Anda selesai menggunakannya, mereka akhirnya akan dilepaskan ketika finaliser berjalan, tapi itu jumlah waktu yang tidak pasti di masa depan ... Jadi, Anda akan melihat penundaan lama saat membuka koneksi baru.

Paling buruk, mereka mungkin telah menonaktifkan kolam koneksi. Mungkin mereka menemukan bahwa setelah beberapa saat aplikasi mereka mengembalikan kesalahan "batas waktu menunggu koneksi" dan menonaktifkan kumpulan koneksi "memecahkan" masalah itu. Namun, ini jauh lebih buruk karena itu berarti Anda membuat koneksi yang sama sekali baru setiap kali - yang mengejutkan sumber daya intensif. Jika Anda memiliki ratusan koneksi ke basis data terbuka, tidak heran Anda melihat masalah kinerja.

Cara yang benar untuk menyelesaikan semua masalah ini adalah membuang koneksi Anda segera setelah Anda selesai menggunakannya. Ide terbaik adalah menjaga koneksi tetap terbuka selama dibutuhkan, dan tidak lagi.

Dean Harding
sumber
1
Bahkan sedikit lebih buruk dari ini. Jika kumpulan didukung cukup, banyak upaya koneksi pada akhirnya akan gagal, termasuk upaya koneksi dari alat manajemen, dan Anda dapat secara efektif mengunci diri kami dari basis data.
Joel Coehoorn
3

Dalam setiap aplikasi serius saya akan mengatakan bahwa itu sangat buruk. Tidak hanya akan membiarkan benda-benda ini mengambang di sekitar membunuh kinerja, itu juga tidak profesional. Berita baiknya adalah Microsoft mengimplementasikan Finalisasi dalam hierarki objek.

~Object()
{
    this.Dispose(false);    
}

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    // ...
}

Ambil System.Data.SqlClient.SqlConnectioncontoh:

System.ComponentModel.Component <- Menerapkan pola buang Finalise.
    |
System.Data.Common.DbConnection
    |
System.Data.SqlClient.SqlConnection

Objek-objek tersebut pada akhirnya akan dibuang tetapi sifat non-deterministik memunculkan malapetaka pada kinerja.

Kekacauan Kekacauan
sumber
0

Nah, untuk satu, Anda tidak memutuskan koneksi. Jadi harus a) Dihilangkan secara otomatis atau b) Dapat bersepeda dan diperbarui meskipun klien tidak menggunakannya.

Saya berasumsi b) karena hit kinerja yang Anda gambarkan. Namun, itu kemungkinan bukan satu-satunya alasan.

Anda HARUS menutup koneksi Anda, terutama di sisi klien, tetapi Anda juga harus mengimplementasikan brankas yang gagal di sisi server. Kalau tidak, Anda hanya memiliki tumpukan ekstra pada server database Anda harus diproses sampai dirilis pada waktu yang tahu.


sumber