asp.net鏈接數據庫超時的解決辦法

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

通過幾天辛苦寫的代碼,終於實現了功能豐富的查詢功能,可是使用的過程當中,卻常常出現上面的錯誤,百思不得其解。寫代碼的時候就擔憂由於功能複雜,效率會很低。數據庫

解決方案一緩存

我想緣由多是併發操做。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接口,強迫釋放資源,這樣就不會出現鏈接數量不夠的問題了。ui

解決方案二spa

解決方法(*):WEB.config 裏面:在數據庫鏈接加 Max Pool Size = 512;server=local;uid=;pwd=;database=2004;Max Pool Size = 512;">一勞永逸。.net

解決方案三設計

估計是鏈接(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 reachedserver

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

問題描述:咱們獲取鏈接超過鏈接池最大值時產生如上異常。一般鏈接池最大值爲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。)

相關文章
相關標籤/搜索