Ketika mencoba untuk menyambung ke database MSSQL melalui ASP.NET online, saya akan mendapatkan yang berikut ini ketika dua atau lebih orang terhubung secara bersamaan:
ExecuteReader membutuhkan Koneksi terbuka dan tersedia. Status koneksi saat ini adalah Menghubungkan.
Situs ini berfungsi dengan baik di server localhost saya.
Ini adalah kode kasarnya.
public Promotion retrievePromotion()
{
int promotionID = 0;
string promotionTitle = "";
string promotionUrl = "";
Promotion promotion = null;
SqlOpenConnection();
SqlCommand sql = SqlCommandConnection();
sql.CommandText = "SELECT TOP 1 PromotionID, PromotionTitle, PromotionURL FROM Promotion";
SqlDataReader dr = sql.ExecuteReader();
while (dr.Read())
{
promotionID = DB2int(dr["PromotionID"]);
promotionTitle = DB2string(dr["PromotionTitle"]);
promotionUrl = DB2string(dr["PromotionURL"]);
promotion = new Promotion(promotionID, promotionTitle, promotionUrl);
}
dr.Dispose();
sql.Dispose();
CloseConnection();
return promotion;
}
Bolehkah saya tahu apa yang mungkin salah dan bagaimana cara memperbaikinya?
Edit: Jangan lupa, string koneksi dan koneksi saya keduanya statis. Saya yakin inilah alasannya. Mohon saran.
public static string conString = ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString;
public static SqlConnection conn = null;
c#
.net
sql-server
ado.net
database-connection
Guo Hong Lim
sumber
sumber
conString
tidak menambahkan apa pun dalam hal kinerja karena tetap di-cache secara default (karena setiap nilai konfigurasi untuk aplikasi saat ini).Jawaban:
Maaf karena hanya berkomentar di tempat pertama, tetapi saya memposting komentar serupa hampir setiap hari karena banyak orang berpikir bahwa akan cerdas untuk merangkum fungsionalitas ADO.NET ke dalam DB-Class (saya juga 10 tahun yang lalu). Sebagian besar mereka memutuskan untuk menggunakan objek statis / bersama karena tampaknya lebih cepat daripada membuat objek baru untuk tindakan apa pun.
Itu bukanlah ide yang baik dalam hal kinerja maupun dalam hal keamanan gagal.
Jangan berburu di wilayah Connection-Pool
Ada alasan bagus mengapa ADO.NET secara internal mengelola Koneksi yang mendasari ke DBMS di ADO-NET Connection-Pool :
Jadi jelas tidak ada alasan untuk menghindari membuat, membuka atau menutup koneksi karena sebenarnya mereka tidak dibuat, dibuka dan ditutup sama sekali. Ini "hanya" sebuah tanda untuk kumpulan koneksi untuk mengetahui kapan koneksi dapat digunakan kembali atau tidak. Tetapi itu adalah tanda yang sangat penting, karena jika koneksi sedang "digunakan" (asumsi kumpulan koneksi), koneksi fisik baru harus openend ke DBMS yang sangat mahal.
Jadi Anda tidak mendapatkan peningkatan kinerja tetapi sebaliknya. Jika ukuran kumpulan maksimum yang ditentukan (100 adalah default) tercapai, Anda bahkan akan mendapatkan pengecualian (terlalu banyak koneksi terbuka ...). Jadi ini tidak hanya akan berdampak besar pada kinerja tetapi juga menjadi sumber kesalahan yang parah dan (tanpa menggunakan Transaksi) area-dumping-data.
Jika Anda bahkan menggunakan koneksi statis, Anda membuat kunci untuk setiap utas yang mencoba mengakses objek ini. ASP.NET adalah lingkungan multithreading secara alami. Jadi ada peluang besar untuk kunci ini yang paling banyak menyebabkan masalah kinerja. Sebenarnya cepat atau lambat Anda akan mendapatkan banyak pengecualian berbeda (seperti ExecuteReader Anda membutuhkan Koneksi terbuka dan tersedia ).
Kesimpulan :
using-statement
untuk membuang dan menutup (dalam kasus Koneksi) secara implisitItu benar tidak hanya untuk Koneksi (meskipun paling menonjol). Setiap implementasi objek
IDisposable
harus dibuang (paling sederhana olehusing-statement
), terlebih lagi diSystem.Data.SqlClient
namespace.Semua hal di atas menentang DB-Class kustom yang merangkum dan menggunakan kembali semua objek. Itulah alasan mengapa saya berkomentar untuk membuangnya. Itu hanya sumber masalah.
Sunting : Berikut kemungkinan penerapan
retrievePromotion
-method Anda :sumber
Saya menemukan kesalahan ini beberapa hari yang lalu.
DALAM kasus saya itu karena saya menggunakan Transaksi di Singleton.
.Net tidak berfungsi dengan baik dengan Singleton seperti yang disebutkan di atas.
Solusi saya adalah ini:
Saya menggunakan HttpContext.Current.Items untuk contoh saya. Kelas DbHelper dan DbHelperCore ini adalah kelas saya sendiri
sumber