[英]Running out of connections in pool
我有一個Web窗體應用程序,它將在GridView中顯示記錄列表,並且通過選中多個復選框,您可以批量刪除記錄。 代碼本身很簡單:
protected void btnDelete_Click(object sender, EventArgs e)
{
int i = 0;
try
{
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox cb = (CheckBox)row.FindControl("ID");
if (cb != null && cb.Checked)
{
int profileID = Convert.ToInt32(GridView1.DataKeys[row.RowIndex].Value);
Profile profile = new Profile(profileID); //instantiate profile
profile.Delete(); //call delete method
i++;
}
}
if (i > 0)
{
//report success to UI
}
}
catch (Exception ex)
{
//report error to UI
}
}
在配置文件構造函數中,它通過打開連接,打開數據讀取器然后設置對象的屬性來水合對象。 我對代碼中的using()
塊一絲不苟,所以每個數據庫連接看起來都像這樣:
using (SQLHelper db = new SQLHelper())
{
db.AddParameterToSQLCommand("@ProfileID", SqlDbType.Int);
db.SetSQLCommandParameterValue("@ProfileID", id);
using (SqlDataReader dr = db.GetReaderByCmd("up_GetProfile"))
{
if (dr.Read())
{
_profileID = id;
if (!dr.IsDBNull(0))
ProfileName = dr.GetString(0);
//... and so on
return true;
}
else
{
return false;
}
}
}
數據讀取器實現了iDisposible,我的助手類也實現了,析構函數如下所示:
public void Dispose()
{
try
{
//Clean Up Connection Object
if (mobj_SqlConnection != null)
{
if (mobj_SqlConnection.State != ConnectionState.Closed)
{
mobj_SqlConnection.Close();
}
mobj_SqlConnection.Dispose();
}
//Clean Up Command Object
if (mobj_SqlCommand != null)
{
mobj_SqlCommand.Dispose();
}
}
catch (Exception ex)
{
throw new Exception("Error disposing data class." + Environment.NewLine + ex.Message);
}
}
當我單步執行代碼時,我看到連接總是一直正確打開和關閉,我的堆棧深度不超過五個或六個調用(我沒有遇到任何遞歸問題),我已經確認所有數據訪問代碼都是正確包裝在使用塊,但我的連接沒有釋放回池中。 相反,我得到這個錯誤:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
這種情況發生在專用的應用程序池中,只有一個用戶刪除了10多個配置文件。 似乎我做的一切都正確,但是我對為什么沒有將連接釋放回池感到困惑。 最多只應有兩個由執行線程打開的連接,當它們超出范圍時,這兩個連接都應該(並且必須執行)。
我顯然做錯了事,但我一生無法弄清楚是什么。
根據我的評論,我將轉換為答案。
似乎您正在嘗試在Command對象之前關閉Connection對象,並且由於Command對象引用了連接,因此它可能會使該連接保持活動狀態。
嘗試切換它們:
//Clean Up Command Object
if (mobj_SqlCommand != null)
{
mobj_SqlCommand.Dispose();
}
if (mobj_SqlConnection != null)
{
if (mobj_SqlConnection.State != ConnectionState.Closed)
{
mobj_SqlConnection.Close();
}
mobj_SqlConnection.Dispose();
}
如果我沒記錯的話,SqlHelper處理不會自動關閉連接。 您需要顯式關閉它。
我們總是在try / final中包裝SqlHelper的用法,並在finally中顯式調用close。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.