錯誤提示:“逾時時間已到。逾時時間已到,但是尚未從池中擷取連接配接。出現這種情況可能是因為所有池連接配接均在使用,并且達到了最大池大小。 ”
經過幾天辛苦寫的代碼,終于實作了功能豐富的查詢功能,但是使用的過程中,卻經常出現上面的錯誤,百思不得其解。寫代碼的時候就擔心因為功能複雜,效率會很低。
解決方案一
我想原因可能是并發操作。DataReader是獨占連接配接的,就是說你的程式可能設計上有問題。比如說最大連接配接設100,假設有100個人同時使用 DataReader正在讀取資料庫内容,那麼當第101人讀取的時候,連接配接池中的連接配接已經沒有了,就會出現上面的錯誤。DataReader是獨占連接配接 的,每個DataReader都要占用一個連接配接。當然這個情況是偶爾出現的,是以會很長時間出現一次,因為隻有同時有超過連接配接池最大連接配接數量 的并發操作才會發生。而且你加大并發數量隻能暫時緩解問題,如果你加大到200個并發連接配接,如果有201人同時操作怎麼辦?你說了你使用 Connection對象的Close()方法,這是不行的,因為Close()方法僅僅是關閉連接配接,但這個連接配接沒有釋放,還是被這個對象占用,要釋放必 須使用Connection的Dispose()方法顯式釋放連接配接才可以,否則這個對象占用的連接配接隻能等到垃圾收集的情況下才能被釋放。這種情況肯定會出 現“逾時時間已到”的錯誤。
解決方法:
1 修改幾個關鍵頁面或通路比較頻繁的資料庫通路操作,使用DataAdapter和DataSet來擷取資料庫資料,不要使用DataReader。
2 在通路資料庫的頁面上使用資料緩存,如果頁面的資料不是經常更新(幾分鐘更新一次)的話,使用Cache對象可以不用通路資料庫而使用緩存中的内容,那麼可以大大減少連接配接數量。
3 修改代碼,把使用Connection對象的地方都在Close()後面加上Dispose()調用。
4 建議對資料庫操作進行大的修改,建立自己的資料庫操作代理類,繼承System.IDisposable接口,強迫釋放資源,這樣就不會出現連接配接數量不夠的問題了。
解決方案二
解決方法(*):WEB.config 裡面:在資料庫連接配接加 Max Pool Size = 512;server=local;uid=;pwd=;database=2004;Max Pool Size = 512;">一勞永逸。
解決方案三
估計是連接配接(Connection)對象沒有Close。倒是不必Dispose,而DataReader用完後應該關閉,但不關閉也沒問題,隻是不關閉的話此連接配接對象就一直不能用,隻要你最終關閉了連接配接對象就不會出問題。
連接配接對象在Open後的操作都放在try塊中,後面跟一個finally塊:conn.Close();
:error connecting: 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
逾時時間已到。逾時時間已到,但是尚未從池中擷取連接配接。出現這種情況可能是因為所有池連接配接均在使用,并且達到了最大池大小。
問題描述:我們擷取連接配接超過連接配接池最大值時産生如上異常。通常連接配接池最大值為100。當我們擷取連接配接超過最大值時,ADO.NET等待連接配接池傳回連接配接而逾時,這樣将抛出如上異常
産生這樣的問題: 連接配接數大于 N 并且超出設定的時間(所有連接配接池中的連接配接都在用,并且等待的時間逾時)
解決辦法:1首先要做的是在我們使用連接配接後立即關閉連接配接
2 其次我們可以通過連接配接字元串中的Max Pool Size = N;來動态擴大連接配接池中的連接配接最大數量。
3 更改連接配接時間 connect timeout=N
首先要保證所有的 connection 連接配接之後 都要手動的關閉, 特别是DataReader(
一個connection對象隻能打開一個DataReader對象,在該datareader對象關閉之前,無法打開其他的datareader對象,知道該datareader 對象調用close 方法為止)
更改 連接配接數量和連接配接時間 根據實際情況而定
為什麼會出現這樣的問題呢?
就是比如買票一樣,五個視窗同時建立,每個人都有自己的等待時間.假如五個建立,占用一個.還有四個空閑. 占用五個.剩下的人需要等待.但是 可能等待的時間很長.這些人都會不耐煩(超出規定時間)的走了.出現異常
正規的解釋
- Connection Pool如何工作的?(摘抄自(http://www.cnblogs.com/qqflying/archive/2012/02/13/2349583.html))
首 先當一個程式執行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。)