您也可以提供幾個連接字串修飾符來控制串連池行為,請參見本主題內下文中“使用連接字串關鍵字控制串連池”這一節。
池的建立和分配
當串連開啟時,將根據一種精確的匹配演算法來建立串連池,該演算法會使串連池與串連中的字串相關聯。每個串連池都與一個不同的連接字串相關聯。當新串連開啟時,如果連接字串不精確匹配現有池,則將建立一個新池。
在以下樣本中,將建立三個新的 SqlConnection 對象,但只需要使用兩個串連池來管理這些對象。請注意,第一個和第二個連接字串的差異在於為 Initial Catalog
分配的值。
SqlConnection conn = new SqlConnection();conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind";conn.Open(); // Pool A is created.SqlConnection conn = new SqlConnection();conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=pubs";conn.Open(); // Pool B is created because the connection strings differ.SqlConnection conn = new SqlConnection();conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind";conn.Open(); // The connection string matches pool A.
串連池一旦建立,直到活動進程終止時才會被毀壞。非活動或空池的維護只需要最少的系統開銷。
串連的添加
串連池是為每個唯一的連接字串建立的。當建立一個池後,將建立多個連線物件並將其添加到該池中,以滿足最小池大小的要求。串連將根據需要添加到池中,直至達到最大池大小。
當請求 SqlConnection 對象時,如果存在可用的串連,則將從池中擷取該對象。若要成為可用串連,該串連當前必須未被使用,具有匹配的事務上下文或者不與任何事務上下文相關聯,並且具有與伺服器的有效連結。
如果已達到最大池大小且不存在可用的串連,則該請求將會排隊。當串連被釋放回池中時,串連池管理程式通過重新分配串連來滿足這些請求。對 Connection 調用 Close 或 Dispose 時,串連被釋放回池中。
警告 建議使用完 Connection 後始終將其關閉,以便串連可以返回到池中。這可以使用 Connection 對象的 Close 或 Dispose 方法來實現。不是顯式關閉的串連可能不會添加或返回到池中。例如,如果串連已超出範圍但沒有顯式關閉,則僅當達到最大池大小而該串連仍然有效時,該串連才會返回到串連池中。
注意 不要在類的 Finalize 方法中對 Connection、DataReader 或任何其他託管對象調用 Close 或 Dispose。在終結器中,僅釋放類直接擁有的非託管資源。如果類不擁有任何非託管資源,則不要在類定義中包含 Finalize 方法。有關更多資訊,請參見記憶體回收編程。
串連的移除
如果串連生存期已到期,或者串連池管理程式檢測到與伺服器的串連已斷開,串連池管理程式將從池中移除該串連。請注意,只有在嘗試與伺服器進行通訊後,才可以檢測到這種情況。如果發現某串連不再串連到伺服器,則會將其標記為無效。串連池管理程式會定期掃描串連池,尋找已釋放到池中並標記為無效的對象。找到後,這些串連將被永久移除。
如果存在與已消失的伺服器的串連,那麼即使串連池管理程式未檢測到已斷開的串連並將其標記為無效,仍有可能將此串連從池中取出。當發生這種情況時,將產生異常。但是,為了將該串連釋放回池中,仍必須將其關閉。
事務支援
串連是根據事務上下文來從池中取出並進行分配的。請求線程和所分配的串連的上下文必須匹配。因此,每個串連池實際上又分為不具有關聯事務內容相關的串連以及 N 個各自包含與一個特定事務內容相關的串連的子部分。
當串連關閉時,它將被釋放回池中,並根據其事務上下文放入相應的子部分。因此,即使分散式交易仍然掛起,仍可以關閉該串連而不會建置錯誤。這樣,您就可以在隨後提交或中止分散式交易。
使用連接字串關鍵字控制串連池
SqlConnection 對象的 ConnectionString 屬性支援連接字串鍵/值對,這些鍵/值對可用於調整串連池邏輯的行為。
下表描述了可用於調整串連池行為的 ConnectionString 值。
名稱 |
預設值 |
說明 |
Connection Lifetime |
0 |
當串連返回到池中時,將對它的建立時間和目前時間進行比較,如果時間間隔超過由 Connection Lifetime 指定的值(以秒為單位),則會毀壞該串連。在聚集配置中可以使用它來強制在運行伺服器和剛聯機的伺服器之間達到Server Load Balancer。 如果值為零 (0),則將使池串連具有最大的逾時期限。 |
Connection Reset |
'true' |
確定在從池中移除資料庫連接時是否將其重設。對於 Microsoft SQL Server 版本 7.0,如果設定為 false,將避免在擷取串連時經曆一個額外的往返過程,但必須注意的是串連狀態(如資料庫上下文)不會被重設。 |
Enlist |
'true' |
當為 true 時,如果存在事務上下文,池管理程式將自動在建立線程的當前事務上下文中登記串連。 |
Max Pool Size |
100 |
池中允許的最大串連數。 |
Min Pool Size |
0 |
池中維護的最小串連數。 |
Pooling |
'true' |
當為 true 時,將從相應的池中取出串連,或者在必要時建立串連並將其添加到相應的池中。 |
串連池的效能計數器
SQL Server .NET Framework 資料提供者添加了幾個效能計數器,它們將使您能夠微調串連池特性,檢測與失敗的串連嘗試相關的間歇性問題,並檢測與對 SQL Server 的逾時請求相關的問題。
下表列出了可以在“.NET CLR 資料”效能物件下的“效能監控器”中訪問的串連池計數器。
計數器 |
說明 |
SqlClient: Current # pooled and non pooled connections |
當前池串連或非池串連的數目。 |
SqlClient: Current # pooled connections |
當前所有池中與特定進程關聯的串連的數目。 |
SqlClient: Current # connection pools |
當前與特定進程關聯的池的數目。 |
SqlClient: Peak # pooled connections |
自特定進程開始以來所有池中的串連數峰值。請注意:此計數器只有在與特定進程執行個體關聯時才可用。_Global 執行個體始終返回 0。 |
SqlClient: Total # failed connects |
開啟串連的嘗試因任何原因而失敗的總次數。 |
注意 將 SQL Server .NET Framework 資料提供者效能計數器與 ASP.NET 應用程式一起使用時,只有 _Global 執行個體是可用的。因此,效能計數器返回的值是所有 ASP.NET 應用程式的計數器值的總和。