我們在寫程序的時候一定都會用到數據庫,我們一定都知道連接是一種寶貴的資源,我們可以通過這樣的連接來獲得數據庫的內容和我們需要的數據。在.NET裡面依然是這樣。我們在使用數據庫資源的時候要做的第一步就是建立一個連接,然後我們可以用這個連接創建一個Command或者DataAdapter對象。
我在寫成程序的時候遇到頁面提示“連接池已滿”之類的話。看到它我知道一定是有打開的連接沒有關閉,在頻繁的數據庫交互中,GC是不可能為我們做到完美,這種問題一般會在一段時間以後消失,但是在執行相同的操作又會出現。不知道各位網友是否碰到這樣的問題,我們可以使用一些簡單的方法來找到這些問題所在,以及注意一些編成習慣可以減少這種事情的發生。
一、DataReader引起的問題
DataReader是一個效率很高但是很耗資源(連接數量)的對象,從它建立到銷毀,他一直和數據庫連著,也就是說它就會占用一個連接數。為了在使用完該對象(reader.Close())以後可以關閉連接釋放資源,我們可以在建立DataReader的時候使用CommandBehavior.CloseConnection選項(構造函數中的一個參數)。當我們使用這個選項的時候,在我們關閉該DataReader的時候我們也同時關閉該對象的連接。
我們知道簡單的代碼看起來舒服,也能很體現我們的編程水平,但是有些簡單的代碼會引入一些我們可能沒有注意的問題,比如:我們在使用SqlHelper(微軟的DataAccess block)的時候 ,我通常使用它作為數據庫的直接交戶層(我的數據庫服務層建立在這之上),我用它可以得到非常豐富的對象其中包括:DataReader,DataSet等等。DataAdapter是一種不用控制連接打開或者關閉的對象(因為它填充的是DataSet對象)。我在處理DataReader的時候很容易忽略當DataReader在其他的層之間傳送的時候,對於這種持續連接的對象處理起來很是麻煩。比如下面的代碼是比較簡單:
MyDataGrid.DataSource = MyObject.GetDataReader();
MyDataGrid.DataBind();
雖然看起來很爽,很簡單,但是使用下面的方法更安全:
IDataReader Dr = MyObject.GetDataReader();
MyDataGrid.DataSource = Dr;
MyDataGrid.DataBind();
Dr.Close();
二、查詢失敗
還有一個需要注意的就是我們在執行查詢語句的時候,通常我們是先打開連接以後在查詢,這樣就容易出問題,查詢出錯了怎麼辦?
我們在執行查詢語句的時候會有這樣或者那樣的原因使得查詢不成功,我通常的做法是使用Catch來捕獲這些錯誤。比如我們在寫一個控件綁定時使用的一個方法GetDataSource。
private DataTable GetDataSource(){
string QueryString = "select * from table1";
SqlConnection conn = new SqlConnection(ConectionString);
SqlCommand cmd ....
return cmd.ExecuteDataSet().Tables[0];
}
上面的方法是很危險的(只寫了部分說明問題就可以了),如果我們在打開連接以後但是查詢的時候執行錯誤,那麼這個打開的連接就不會被釋放(如果有自定義的錯誤頁面則會跳到該頁面)。我們通常應該將執行查詢的部分放在try...catch裡面。這樣在出現錯誤的時候我們還是有機會關閉這些連接,最好使用try....catch....finally。我在finally裡面處理所有已經打開的連接感覺還是比較安全的。
好了,說了這麼多,不廢話了,總結一下:在使用DataReader的時候要特別注意,因為DataSet是內存緩沖所以他災區的數據以後就自動斷開了連接。在執行查詢語句的時候也要特別注意,在用完對象銷毀(Dispose)他是一個好的做法。