來源: http://www.25175.com 作者: onrd
使用串連池
串連到資料庫伺服器通常由幾個需要軟長時間的步驟組成。必須建立物理通道(例如通訊端或具名管道),必須與伺服器進行初次串連,必須分析連接字串資訊,必須由伺服器對串連進行身分識別驗證,等等。
實際上,大部份的應用程式都是使用一個或幾個不同的串連配置。當應用程式的資料量和訪問量大的時候,這意味著在運行應用程式的過程中,許多相同的串連將反覆地被開啟和關閉,從而會引起資料庫伺服器效率低下甚至引發程式崩潰。為了確保應用程式的穩定和降低效能成本,我們可以在ADO.NET中使用稱為串連池的最佳化方法來管理維護串連。
www.25175.net
串連池可以減少建立串連的次數。定義最小串連數(固定串連數),當使用者在串連上調用 Open,串連池就會檢查池中是否有可用的串連。如果發現有串連可用,會將該串連返回給調用者,而不是建立新串連。應用程式在該串連上調用 Close 時,串連池會判斷該串連是否在最小串連數之內,如果“是”會將串連回收到活動串連池中而不是真正關閉串連,否則將燒毀串連。串連返回到池中之後,即可在下一個 Open 調用中重複使用。
建立串連池
以下樣本使用C# 串連SQL資料庫:
class DbConn
{
//using System.Data;
//using System.Data.SqlClient;
private const int MaxPool = 10; //最大串連數
private const int MinPool = 5; //最小串連數
private const bool Asyn_Process = true; //設定非同步訪問資料庫
private const bool Mars = true; //在單個串連上得到和管理多個、僅向前引用和唯讀結果集(ADO.NET2.0)
private const int Conn_Timeout = 15; //設定串連等待時間
private const int Conn_Lifetime = 15; //設定串連的生命週期
private string ConnString = ""; //連接字串
private SqlConnection SqlDrConn = null; //連線物件
public DbConn()//建構函式
{
ConnString = GetConnString();
SqlDrConn = new SqlConnection(ConnString);
}
private string GetConnString()
{
return "server=localhost;"
+ "integrated security=sspi;"
+ "database=pubs;"
+ "Max Pool Size=" + MaxPool + ";"
+ "Min Pool Size=" + MinPool + ";"
+ "Connect Timeout=" + Conn_Timeout + ";"
+ "Connection Lifetime=" + Conn_Lifetime + ";"
+"Asynchronous Processing=" + Asyn_Process + ";";
//+ "MultipleActiveResultSets=" + Mars + ";";
}
public DataTable GetDataReader(string StrSql)//資料查詢
{
//當串連處於開啟狀態時關閉,然後再開啟,避免有時候資料不能及時更新
if (SqlDrConn.State == ConnectionState.Open)
{
SqlDrConn.Close();
}
try
{
SqlDrConn.Open();
SqlCommand SqlCmd = new SqlCommand(StrSql, SqlDrConn);
SqlDataReader SqlDr = SqlCmd.ExecuteReader();
if (SqlDr.HasRows)
{
DataTable dt = new DataTable();
//讀取SqlDataReader裡的內容
dt.Load(SqlDr);
//關閉對象和串連
SqlDr.Close();
SqlDrConn.Close();
return dt;
}
return null;
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
return null;
}
finally
{
SqlDrConn.Close();
}
}
}
通過調用 SqlDrConn.Open()方法開啟串連,這時候串連池就會初始化並建立設定的最小串連數。想更清楚瞭解到串連池的狀況可以通過SQL的查詢分析器執行預存程序sp_Who,它會列出當前的資料庫進程,查看loginname、dbname可以區分使用者的串連資訊,但要注意的是登入查詢分析器本身會使用兩個串連,所以最好用另一個使用者名稱登入查詢分析器。使用此方法還有一個麻煩地方就是要經常按“執行查詢”以更新進程資訊。還有另一種方法個人認為較好的,通過 控制台→管理工具→效能,右擊添加計算機,效能物件選擇SQlServer:General Statistics(常規統計)然後計算機選擇User Connections(使用者串連)最後按“添加”就可以即時查看當前串連數。
到了這裡,串連池已經實現了, 但問題往往會出現在運行過程中。如串連池的串連數滿了該怎樣處理?在這裡我們應該合理設定連接字串中的Connect Timeout屬性和Connection Lifetime屬性(上面有解釋)延長等待時間,儘可能地在每次使用完串連之後調用Close方法關閉串連。但從中也有沒法避免的,當串連數滿了並且申請串連的時間超過設定串連等待的時間時,程式將會引發InvalidOperationExceptio異常,我們可以通過捕獲此異常向使用者介面提示“系統正忙,請稍後再串連……”之類的資訊來緩解這種情況。此外,也有另一種方法來解決這種情況,就是利用ADO.NET 2.0 新特性“非同步進程”,對資料庫進行非同步作業,確保串連能夠及時調用Close方法關閉串連,這樣能大大減少正在使用的串連數。
使用方法:在連接字串中加上Asynchronous Processing=true 表示使用非同步處理操作。
當應用程式不再需要用到串連池的時候可以使用ClearPool 或 ClearAllPools方法清空串連池也可作重設串連池使用,方法如下:
SqlConnection.ClearPool(SqlConnection connection) 清空關聯的串連池
SqlConnection.ClearAllPools() 清空所有串連池
調用上述方法,如果串連正在使用,串連池會做相應標記,等串連關閉時自動燒毀。
小結C#串連池
優點:當資料庫操作和訪問頻繁的時候,減少建立串連和開啟串連所耗的時間,提升資料庫伺服器的效能。
缺點:資料庫連接池中可能存在著多個沒有被使用的串連一直串連著資料庫,這意味著資源的浪費。