異常:超時時間已到。超時時間已到,但是尚未從池中獲取連接。出現這種情況可能是因為所有池連接均在使用,並且達到了最大池大小。
原因分析:asp.net的數據庫連接池的連接都被占用了。
很多同學都表示不解,表示沒有過數據庫連接池。
怎么開啟數據庫連接池?
數據庫連接池在哪里,很多同學都以為應該在數據庫服務器,其實不對,連接池是在應用服務器上,有asp.net管理連接池。
數據庫連接池在哪里呢,我們用代碼驗證它的存在。
一、web.config的連接字符串的配置
<connectionStrings> <add name="SQLConnString1" connectionString="Server=192.168.1.88;Database=CloudLightApp;User Id=sa;Password=xyz;" /> </connectionStrings>
二、運行沒報異常代碼
for (int i = 0; i < 100; i++) { var reader = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringLocalTransaction, System.Data.CommandType.Text, "select * from T_MOB_ENTERPRISE"); Response.Write(i.ToString() + "<br />"); }
三、運行報異常代碼
for (int i = 0; i < 101; i++) { var reader = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringLocalTransaction, System.Data.CommandType.Text, "select * from T_MOB_ENTERPRISE"); Response.Write(i.ToString() + "<br />"); }
比較上面這段代碼,發現區別就在於前一個執行100次查詢,后一個執行了101次查詢。后一個查詢拋出【超時時間已到,但是尚未從池中獲取連接】異常
原因是:微軟默認給我們啟動了連接池,默認的連接數為100,上面的連接字符串等價於
<connectionStrings> <add name="SQLConnString1" connectionString="Server=192.168.1.88;Database=CloudLightApp;User Id=sa;Password=xyz;Max Pool Size = 100;Pooling = True;" /> </connectionStrings>
由於我們的代碼每次查詢完以后都沒釋放連接,導致101次查詢時,沒有可用的連接。
為什么要開啟連接池?
主要是為了性能考慮,建立一個tcp連接需要三次握手,比較費時! 連接池復用連接,用完不關閉,直接把連接退還給連接池!
為什么會報超時時間已到,但是尚未從池中獲取連接錯誤
是因為連接池有個最大的數目控制,Max Pool Size 。如果連接池最大設置成100,已經申請到了100個連接,並且100個連接都被占用,當第101個連接請求時,會報上面的異常,因為連接池沒有可用的連接了。
怎么避免上面的錯誤
1、及時的關閉連接
調整成下面的代碼,就會發現執行101次查詢都只有1個tcp連接,后續的100次查詢都是用的同一個連接。因為用using后,編譯器自動會生成釋放連接的代碼。連接池的中一個連接循環使用!
for (int i = 0; i < 101; i++) { using (var reader = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringLocalTransaction, System.Data.CommandType.Text, "select * from T_MOB_ENTERPRISE")) { Response.Write(i.ToString()+"<br />"); } }
有圖有真相
2、適當的調整Max Pool Size
如果並發量大,可以調整為512,1024等