天天看點

關于ADO.NET連接配接池

前幾天同僚問我一個問題,一種cs架構的程式,直接把sql server作為服務端,每個用戶端直接連接配接資料庫操作,如果用戶端打開的數量過多時sql server的連接配接數将會特别高,資料庫端形成性能瓶頸,這種情況下怎麼辦?想了想,造成這種情況的原因是ado.net的内部機制造成的。ado.net中為了提高性能,是以使用了連接配接池,這樣每個請求就不必都建立一個連接配接,然後認證,然後執行sql,而是從連接配接池中直接取出連接配接執行sql,執行完成後也并不是真正關閉連接配接,而是将該連接配接重新放回連接配接池中。如果有100個用戶端,每個用戶端在使用一段時間後連接配接池中儲存了10個連接配接,那麼在這種情況下,即使不在用戶端做任何操作,sql server上都有1000個連接配接,這樣不出性能問題才怪。

既然是連接配接池的問題,那麼我就針對該問題想到了2個解決辦法:

1.關閉ado.net的連接配接池,每次執行sql時都是建立一個連接配接執行,然後關閉。這樣做将使資料查詢有所減慢(每次都建立連接配接,每次都認證,當然會慢了),不過這個慢是毫秒級的,一般感覺不到的,但是如果一個操作就涉及到幾百個sql語句的情況可能會明細感覺到減慢。修改方法特别簡單,都不用修改代碼,在資料庫連結字元串中加入pooling=false;即可。

2.修改架構,這種cs架構除了性能問題外還會出現其他的比如安全上的問題。可以将直接連資料庫的方法改成連接配接服務,這其中可以使用remoting、web服務等,當然現在可以統一用wcf了。這樣做就隻有服務程式去連接配接資料庫,而用戶端隻連接配接服務程式,這樣就不會出現連接配接池造成的瓶頸。不過這樣做代碼修改量很大,若真要改還是很痛苦的。

以下是網上找到的一篇介紹ado.net連接配接池的文章,感覺不錯。

連接配接池允許應用程式從連接配接池中獲得一個連接配接并使用這個連接配接,而不需要為每一個連接配接請求重建立立一個連接配接。一旦一個新的連接配接被建立并且放置在連接配接池中,應用程式就可以重複使用這個連接配接而不必實施整個資料庫連接配接建立過程。

當應用程式請求一個連接配接時,連接配接池為該應用程式配置設定一個連接配接而不是重建立立一個連接配接;當應用程式使用完連接配接後,該連接配接被歸還給連接配接池而不是直接釋放。

如何實作連接配接池

確定你每一次的連接配接使用相同的連接配接字元串(和連接配接池相同);隻有連接配接字元串相同時連接配接池才會工作。如果連接配接字元串不相同,應用程式就不會使用連接配接池而是建立一個新的連接配接。

優點

使用連接配接池的最主要的優點是性能。建立一個新的資料庫連接配接所耗費的時間主要取決于網絡的速度以及應用程式和資料庫伺服器的(網絡)距離,而且這個過程通常是一個很耗時的過程。而采用資料庫連接配接池後,資料庫連接配接請求可以直接通過連接配接池滿足而不需要為該請求重新連接配接、認證到資料庫伺服器,這樣就節省了時間。

缺點

資料庫連接配接池中可能存在着多個沒有被使用的連接配接一直連接配接着資料庫(這意味着資源的浪費)。

技巧和提示

1. 當你需要資料庫連接配接時才去建立連接配接池,而不是提前建立。一旦你使用完連接配接立即關閉它,不要等到垃圾收集器來處理它。

2. 在關閉資料庫連接配接前確定關閉了所有使用者定義的事務。

3. 不要關閉資料庫中所有的連接配接,至少保證連接配接池中有一個連接配接可用。如果記憶體和其他資源是你必須首先考慮的問題,可以關閉所有的連接配接,然後在下一個請求到來時建立連接配接池。

連接配接池faq

1. 何時建立連接配接池?

當第一個連接配接請求到來時建立連接配接池;連接配接池的建立由資料庫連接配接的連接配接字元創來決定。每一個連接配接池都與一個不同的連接配接字元串相關。當一個新的連接配接請求到來時如果連接配接字元串和連接配接池使用的字元串相同,就從連接配接池取出一個連接配接;如果不相同,就建立一個連接配接池。

2. 何時關閉連接配接池?

當連接配接池中的所有連接配接都已經關閉時關閉連接配接池。

3. 當連接配接池中的連接配接都已經用完,而有新的連接配接請求到來時會發生什麼?

當連接配接池已經達到它的最大連接配接數目時,有新的連接配接請求到來時,新的連接配接請求将放置到連接配接隊列中。當有連接配接釋放給連接配接池時,連接配接池将新釋放的連接配接配置設定給在隊列中排隊的連接配接請求。你可以調用close和dispose将連接配接歸還給連接配接池。

4. 我應該如何允許連接配接池?

對于.net應用程式而言,預設為允許連接配接池。(這意味着你可以不必為這件事情做任何的事情)當然,如果你可以在sqlconnection對象的連接配接字元串中加進pooling=true;確定你的應用程式允許連接配接池的使用。

5. 我應該如何禁止連接配接池?

ado.net預設為允許資料庫連接配接池,如果你希望禁止連接配接池,可以使用如下的方式:

1) 使用sqlconnection對象時,往連接配接字元串加入如下内容:pooling=false;

2) 使用oledbconnection對象時,往連接配接字元串加入如下内容:ole db services=-4;