Timeout expired 超時時間已到. 達到了最大池大小 錯誤及Max Pool Size設置 SQL Timeout超時的處理方法

SQL Timeout超時的處理方法

 

第一步:修改Web.config配置文件。在數據庫鏈接字符串中加上鍊接時間Connect Timeout,根據實際狀況定時間。html

  1. <!--鏈接數據庫-->  
  2. <connectionStrings>  
  3.      <add name="strConnDB" connectionString=" Data Source=192.168.*.*;Initial Catalog=DatabaseName;Persist Security Info=True;User id=sa;Password=password;pooling=true;max pool size=800;min pool size=300;<span style="color:#FF0000;">Connect Timeout=500</span>;"/>  
  4. </connectionStrings>  


第二步:修改command對象的CommandTimeout屬性。 數據庫

  1. SqlCommand cmd = new SqlCommand();  
  2. cmd.CommandTimeout = 180;  

這裏設置的時間是180秒,即三分鐘!可根據須要設置,若是過長,也能夠設置爲0,當此屬性設置爲0時表示不限制時間。此屬性值應該慎用。

到此爲止,問題完美解決。

補充:
SqlCommand.CommandTimeOut:獲取或設置在終止執行命令的嘗試並生成錯誤以前的等待時間。
SqlConnection.ConnectionTimeout:獲取在嘗試創建鏈接時終止嘗試並生成錯誤以前所等待的時間。瀏覽器

 

 

 

參考數據庫連接串:服務器

<add key="data" value="server=192.168.1.123; Port=3306; uid=root; pwd=root;database=data;pooling=true;min pool size=5;max pool size=512;connect timeout = 20; "/>  

 

查看應用程序池佔用數量:post

select * from sysprocesses where dbid= db_id('數據庫名')

 

 

Max Pool Size:若是未設置則默認爲100,理論最大值爲32767。最大鏈接數是鏈接池能申請的最大鏈接數,若是數據庫鏈接請求超過此數,後面的數據庫鏈接請求將被加入到等待隊列中,這會影響以後的數據庫操做。在等待隊列中,默認等待與服務器的鏈接的時間爲15秒。ui

 

中文錯誤:url

超時時間已到。超時時間已到,可是還沒有從池中獲取鏈接。出現這種狀況多是由於全部池鏈接均在使用,而且達到了最大池大小。spa

英文錯誤:.net

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. code

問題描述:咱們獲取鏈接超過鏈接池最大值時產生如上異常。一般鏈接池最大值爲100。當咱們獲取鏈接超過最大值時,ADO.NET等待鏈接池返回鏈接而超時,這樣將拋出如上異常
解決辦法:首先要作的是在咱們使用鏈接後當即關閉鏈接。若是沒有關閉鏈接那麼鏈接將保存到鏈接池中知道GC來銷燬。這種狀況下你覺得鏈接池沒有到達最大值但實際上鍊接池已經到達了最大值 其次咱們能夠經過鏈接字符串中的Max Pool Size = N;來動態擴大鏈接池中的鏈接最大數量。

說明: 

也就是在connectionString中若是未指定max pool size的值,則max pool size=100,當訪問人員同時鏈接數據庫的數量爲101人時,則等待SqlConnection.ConnectionTimeout設置的時間(默認是15 秒)後,仍是沒有可用的Connection則會出現上面的錯誤。

當咱們設置爲:

"Server=(local); Integrated Security=SSPI; Database=Northwind; Max Pool Size=512; Min Pool Size=5"  時。則訪問人員同時鏈接數據庫的數量爲513時,則等待SqlConnection.ConnectionTimeout設置的時間(默認是15 秒)後,仍是沒有可用的Connection則 就會出現上面的錯誤。

 

 

-           Connection Pool  是什麼呢 ?
每當程序須要讀寫數據庫的時候。Connection.Open()會使用ConnectionString鏈接到數據庫,數據庫會爲程序創建 一個鏈接,而且保持打開狀態,此後程序就可使用T-SQL語句來查詢/更新數據庫。當執行到Connection.Close()後,數據庫就會關閉當 前的鏈接。很好,一切看上去都是如此有條不紊。
 
可是若是個人程序須要不定時的打開和關閉鏈接,(好比說 ASP.Net 或是 Web Service ),例如當Http Request發送到服務器的時候、,咱們須要打開Connection 而後使用Select* from Table 返回一個DataTable/DataSet給客戶端/瀏覽器,而後關閉當前的Connection。那每次都Open/Close Connection 如此的頻繁操做對於整個系統無疑就成了一種浪費。
 
ADO.Net Team就給出了一個比較好地解決方法。將先前的Connection保存起來,當下一次須要打開鏈接的時候就將先前的Connection 交給下一個鏈接。這就是Connection Pool。


-           Connection Pool  如何工做的?
首先當一個程序執行Connection.open()時候,ADO.net就須要判斷,此鏈接是否支持Connection Pool (Pooling 默認爲True),若是指定爲False, ADO.net就與數據庫之間建立一個鏈接(爲了不混淆,全部數據庫中的鏈接,都使用」鏈接」描述),而後返回給程序。

若是指定爲 True,ADO.net就會根據ConnectString建立一個Connection Pool,而後向Connection Pool中填充Connection(全部.net程序中的鏈接,都使用」Connection」描述)。填充多少個Connection由Min Pool Size (默認爲0)屬性來決定。例如若是指定爲5,則ADO.net會一次與SQL數據庫之間打開5個鏈接,而後將4個Connection,保存在 Connection Pool中,1個Connection返回給程序。

 
當程序執行到Connection.close() 的時候。若是Pooling 爲True,ADO.net 就把當前的Connection放到Connection Pool而且保持與數據庫之間的鏈接。

同時還會判斷Connection Lifetime(默認爲0)屬性,0表明無限大,若是Connection存在的時間超過了Connection LifeTime,ADO.net就會關閉的Connection同時斷開與數據庫的鏈接,而不是從新保存到Connection Pool中。

(這個設置主要用於羣集的SQL 數據庫中,達到負載平衡的目的)。若是Pooling指定爲False,則直接斷開與數據庫之間的鏈接。

 
而後當下一次Connection.Open() 執行的時候,ADO.Net就會判斷新的ConnectionString與以前保存在Connection Pool中的Connection的connectionString是否一致。

(ADO.Net會將ConnectionString轉成二進制流,所 以也就是說,新的ConnectionString與保存在Connection Pool中的Connection的ConnectionString必須徹底一致,即便多加了一個空格,或是修改了Connection String中某些屬性的次序都會讓ADO.Net認爲這是一個新的鏈接,而重新建立一個新的鏈接。因此若是您使用的UserID,Password的認 證方式,修改了Password也會致使一個Connection,若是使用的是SQL的集成認證,就須要保存兩個鏈接使用的是同一個)。

而後 ADO.net須要判斷當前的Connection Pool中是否有可使用的Connection(沒有被其餘程序所佔用),若是沒有的話,ADO.net就須要判斷ConnectionString設 置的Max Pool Size (默認爲100),若是Connection Pool中的全部Connection沒有達到Max Pool Size,ADO.net則會再次鏈接數據庫,建立一個鏈接,而後將Connection返回給程序。

若是已經達到了 MaxPoolSize,ADO.net就不會再次建立任何新的鏈接,而是等待Connection Pool中被其餘程序所佔用的Connection釋放,這個等待時間受SqlConnection.ConnectionTimeout(默認是15 秒)限制,也就是說若是時間超過了15秒,SqlConnection就會拋出超時錯誤(因此有時候若是SqlConnection.open()方法拋 出超時錯誤,一個可能的緣由就是沒有及時將以前的Connnection關閉,同時Connection Pool數量達到了MaxPoolSize。)

若是有可用的Connection,從Connection Pool 取出的Connection也不是直接就返回給程序,ADO.net還須要檢查ConnectionString的ConnectionReset屬性 (默認爲True)是否須要對Connection 最一次reset。這是因爲,以前從程序中返回的Connection可能已經被修改過,好比說使用 SqlConnection.ChangeDatabase method 修改當前的鏈接,此時返回的Connection可能就已經不是鏈接當前的Connection String指定的Initial Catalog數據庫了。因此須要reset一次當前的鏈接。可是因爲全部的額外檢查都會增大ADO.net Connection Pool 對系統的開銷。

相關文章
相關標籤/搜索