連接數(shù)據(jù)庫時發(fā)生"一般性網(wǎng)絡(luò)錯誤"的另類解釋
2024-07-21 02:08:40
供稿:網(wǎng)友
連接數(shù)據(jù)庫時發(fā)生
"一般性網(wǎng)絡(luò)錯誤"
的另類解釋
revision history:
version
date
creator
description
1.0.0.1
2003-11-15
鄭昀
草稿
implementation scope:
本文檔將說明出現(xiàn)一種不容易想到原因的訪問數(shù)據(jù)庫時發(fā)生“一般性網(wǎng)絡(luò)錯誤”,錯誤報告的來源是adodb,錯誤號是“-2147467259,或者0x80004005”。
繼續(xù)閱讀之前,我們假設(shè)您熟悉以下知識:
n microsoft sql server 2000
n microsoft ado
關(guān)鍵詞:
sql server、ado、dbmssocn、0x80004005
現(xiàn)象
一天,突然有這么一個問題擺在面前:
用戶瀏覽工作流系統(tǒng)時,突然跑出來這么一個錯誤:
microsoft vbscript 編譯器錯誤 錯誤 '800a03f6'
缺少 'end'
/iishelp/common/500-100.asp,行242
microsoft ole db provider for sql server 錯誤 '80004005'
[dbmssocn]一般性網(wǎng)絡(luò)錯誤。請檢查網(wǎng)絡(luò)文檔。
/xxx/yyyframe.asp,行23
經(jīng)過排查,確定真正的原因在于調(diào)用ado連接sql server 2000時,發(fā)生異常,錯誤描述就是“[dbmssocn]一般性網(wǎng)絡(luò)錯誤。請檢查網(wǎng)絡(luò)文檔。”,至于那個“microsoft ole db provider for sql server 錯誤 '80004005'”其實并沒有太多意義。
為什么會突然出現(xiàn)“[dbmssocn]一般性網(wǎng)絡(luò)錯誤。”呢?
服務(wù)器頁面調(diào)用的是封裝好的com+ sta 組件,連接sql server 2000的其實是這個組件。
后來又提供一個比較重要的信息,當這些事情發(fā)生的時候,注意到com+應(yīng)用的進程占用了200mb的內(nèi)存。
初步的猜想
以前曾經(jīng)在其他地方遇到過這種錯誤。
但是,那是因為網(wǎng)卡或者網(wǎng)線閃斷(“network is down”),造成連接數(shù)據(jù)庫失敗,服務(wù)又不停地試著去連接。不知道在什么情況下,服務(wù)不斷報告:
錯誤環(huán)境說明:運行sql命令從數(shù)據(jù)庫讀取記錄時發(fā)生com異常;
錯誤說明:[dbmssocn]一般性網(wǎng)絡(luò)錯誤。請檢查網(wǎng)絡(luò)文檔。
錯誤號:-2147467259
“[dbmssocn]”指的是,當前用tcp/ip協(xié)議與數(shù)據(jù)庫通信。
但是,這次環(huán)境的網(wǎng)絡(luò)質(zhì)量沒有問題。
模擬試驗
專家指出可能是因為同一臺服務(wù)器和sql server之間的連接都沒有close,所以導(dǎo)致連接達到被允許的最大數(shù)目,從而被全部關(guān)閉。
于是我們試驗,看看一臺服務(wù)器被允許與sql server建立最多多少個連接。
更多信息
測試程序中重用了原工程中initadocmd (_command** ppicmd)方法。
這個方法利用ado.command::put_activeconnection方法來建立數(shù)據(jù)庫連接的:
varconn = _bstr_t("provider=sqloledb.1;……”);
hr = t_picmd->put_activeconnection(varconn);
在windows xp環(huán)境中,循環(huán)調(diào)用這個函數(shù)到了1980次,程序就出現(xiàn)幾秒鐘的停頓。之后,就得到0x80004005的錯誤返回值。這個值是由put_activeconnection方法返回的,并不是異常。所以看不到ado異常描述。
我們通過測試程序停滯時,立刻用一個vbs腳本再次請求建立數(shù)據(jù)庫連接。于是,vbs腳本一起停滯,隔了幾秒鐘后,拋出異常,錯誤描述為:
"[dbnetlib][connectionopen (preloginhandshake()).]一般性網(wǎng)絡(luò)錯誤。請檢查網(wǎng)絡(luò)文檔。"
之后的1981、1982、...次put_activeconnectio調(diào)用,都會是同一個錯誤返回值。
在sql server事件探查器中,看到1980次調(diào)用之前,都只有audit login事件。除非關(guān)閉測試程序,才會唰地一下所有的audit logout事件出來了。
有時候,當?shù)?981次建立連接的請求被sql server 2000認為超出允許范圍時,sql server 2000會主動將這一千多個的連接同時全部中斷。于是乎,在sql server事件探查器中,你也可以看到唰地一下所有的audit logout事件出來了。
如果測試程序維持著這些數(shù)據(jù)庫連接的話,內(nèi)存會持續(xù)增長,如下所示:
在winxp上(win2000上允許連接的數(shù)目少),
情況1:
單純反復(fù)執(zhí)行ado.command::put_activeconnection,則只有“audit login”事件,沒有l(wèi)ogout事件。這種請求最多達到1980之后,就會出現(xiàn)“一般性網(wǎng)絡(luò)錯誤”。
情況2:
如果是反復(fù)執(zhí)行
ado.command::put_activeconnection方法,然后又執(zhí)行了查詢,返回記錄集,則這種循環(huán)最多達到483之后,就會出現(xiàn)“一般性網(wǎng)絡(luò)錯誤”。
在實際測試中,第1種情況,最開始demo用了6mb內(nèi)存,最后累積的內(nèi)存是:104mb。
第2種情況下,最開始demo用了6mb內(nèi)存,最后累積的內(nèi)存是:39.5mb。
你可以通過下面的sql語句察看當前與sql server保持的連接都來自于哪里,有多少個:
select dbid,db_name(dbid) as dbname,hostname,status,last_batch
from sysprocesses
where db_name(dbid)='%yourdatabasename%' and (last_batch > 'yy-mm-dd mm:ss:00')
order by last_batch desc
總結(jié):
雖然這種情況出現(xiàn)的比較罕見,但是如果排除了網(wǎng)絡(luò)質(zhì)量原因,你也許可以注意一下當前服務(wù)器與sql server的connection數(shù)目是否維持在一個正在高漲的數(shù)量。
當連接不斷增加的時候,就要當心,服務(wù)器連接數(shù)據(jù)庫是有一定限制的,而且達到最大值后,其他程序再次請求連接時,就可能得到“一般性網(wǎng)絡(luò)錯誤”的警告,而且錯誤號80004005也并沒有說明到底發(fā)生了什么,sql server和ado并不會告訴你連接數(shù)已經(jīng)達到最大值。
disclaimers:
本文檔所包含的信息代表了在發(fā)布之日,zhengyun對所討論問題的當前看法。本文檔不應(yīng)理解為zhengyun一方的承諾,zhengyun不保證所給信息在發(fā)布之日以后的準確性。
本文檔僅供參考。
用戶必須遵守所有適用的版權(quán)法。在不對版權(quán)法所規(guī)定的權(quán)利加以限制的情況下,如未得到 zhengyun和csdn.net明確的書面許可,不得出于任何目的、以任何形式或手段(電子的、機械的、影印、錄制等等)復(fù)制、傳播本文的任何部分,也不得將其存儲或引入到檢索系統(tǒng)中。
thank tian&wu
writen by zhengyun_ustc(at)hotmail.com