DataReader不奇怪,该出手时就出手!
夜里三點多,剛完成微博粉絲精靈V3.763的微博升級,上來看看,剛看到一篇文章:【原】關于使用DataReader的一個很奇怪的問題,不應該用DataReader?
于是準備花點時間解答下,順便為這個月增添一篇文章。
?
關于DataReader,以前寫過一篇文章,可參考:DataReader?鏈接關閉解惑篇?
?
下面將對原文,解答兩個問題:
?
一:?DataReader、DataTable、DataSet 的簡單關系:
?
這里先取原文的第一句話:.net讀取數據集有兩種方式:DataSet?和?DataReader
解答:.net 的Command操作里,默認可以有三種返回:DataReader、DataTable、DataSet
?
這三者的簡單關系為:
?
DataReader?快速只向前讀的流,需要開發者自己去關閉流。DataTable?一個容器,把DataReeader讀到DataTable容器后關閉流。
DataSet 一個大容器,里面可放置多個DataTable。
因此開發者,首先要明白這三者的簡單關系,才不至于亂猜。
?
二:數據庫鏈接、鏈接池、close與dispose
?
這里再取原文的第N句話:在sqlserver(2000)中查看進程,有非常多的sleeping進程,直到最后打開頁面,提示超時,說連接池滿。
?
解答:默認mssql的鏈接數是有限的,大體在100多個,簡單的說你可以open 100多次而不關閉,超過后再open就會出現鏈接池不夠的現象。
這之間的簡單關系為:
?
第一次Open出鏈接時,連接數據庫(由于是首次建立鏈接,需要初始化先多信息,就是傳說的性能問題)然后你Close時,數據庫斷開鏈接,同時把鏈接狀態改成sleep,但是不銷毀(為了下次建立鏈接時省掉初始化,避免傳說中的性能問題),這個不銷毀的鏈接,放到一個池里面,被稱之為鏈接池。
如果你Dispose(),則會把鏈接從池里銷毀,當然下次鏈接就會開始新的初始化。
?
下面就會有很多種情況出現:
?
情況一:一個線程的正常操作:
?
如果使用時一個流程下來,是按順序的open->close-open->close 狀態,那么始終只用到一個鏈接(從連接池里進進出出),基本沒有過多的初始化問題,傳說性能好。
?
情況二:多個線程的不正常操作:
?
如果你一個鏈接,在Open狀態,這時候另一個線程也要打開鏈接,發現鏈接池沒有時,就會重新到數據庫建一個鏈接(又開始初始化,一堆信息,最后產生一個鏈接)。
如果你所有的鏈接全在Open,不關閉,或者時間拖的很多,在其它線程要鏈接的時候,你的鏈接還沒關閉,在產生100多個鏈接后,數據庫最大數滿了,就會出現“鏈接池已滿”的情況。?
?
情況三:多個線程的正常操作:
?
如果你懂的每個鏈接打開后,都快速關閉,通常一個正常語句的操作時間在0.001-0.1秒左右,這樣關閉的鏈接就回到池里,可以快速供給其它線程使用。
這樣,僅需要幾十個鏈接,就可以循環的使用處理多線程問題。?
?
簡單的假設:
如果一個操作open到close,用時0.1秒一次, 那么一個鏈接在1秒內可以處理10次操作。而100個鏈接最大數就可以支持1000次操作。
簡單的說就是1秒可以并發操作1000次以上,這對中小網站來說,處理是相當容易的事。
而新手容易犯的錯誤,就是鏈接打開后,長時間的不關閉,最后導致在多線程的情況下,把數據庫鏈接資源用盡了,出現了錯誤而不得知。?
?
進一步的假設:
在很多的程序處理中,對數據庫的操作時間,往往是不平均的,這就需要有點經驗的程序開發者,花點時間,來搞好這最大并發問題,通常是:
對長時間查詢的,使用緩存(避免二次查詢),或者集中使用隊列(因為使用隊列,就一個鏈接就可以搞定了,反正是開了讀和關,然后下一個又是開了讀和關,始終是一個鏈接),當然使用隊列也要看情況。
對于時間短的,直接處理就可以了。
?
其實說白了,越往上,就越是“看情況處理”,沒有啥定律,要是有,那就是數據庫的最大鏈接數,無論你怎么耍流氓,反正你不能讓它一次性給用完。?
?
補充點:
在sqlserver(2000)中查看進程,有非常多的sleeping進程,直到最后打開頁面,提示超時,說連接池滿,為什么,既然已經了很多 sleeping 的數據庫連接, 為什么還會出現 不能連接數據庫 的問題呢???
答:
對于ADO.NET,它有一種機制,來分析是使用產生新的會話還是直接從鏈接池中返回,例如,不同的數據庫鏈接,它會產生新的鏈接,而不會從原有鏈接池里返回。而對于mssql,可能某種檢測機制原因(不同的線程或進程鏈接),mssql分析后直接是為你產生新的鏈接,而不是從sleep狀態的鏈接池返回,因此,原來的sleep無法復用,再次產生新的鏈接,就報鏈接池滿了。
轉載于:https://www.cnblogs.com/cyq1162/archive/2012/04/21/2460964.html
總結
以上是生活随笔為你收集整理的DataReader不奇怪,该出手时就出手!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java: IE Firefox下载文
- 下一篇: UDP协议下数据的传输分析