The information in this article applIEs to:
ü Microsoft SQL Server 2000,7.0
ü Microsoft ADO 2.5
數據庫服務器:Microsoft SQL Server 2000以及7.0;
數據庫服務器補丁:Microsoft SQL Server 2000 ServicePack1;
ADO名稱:Microsoft Data Access - ActiveX Data Objects 2.5 Type Library
ADO版本:2.61.7326.0
執行下面的VB代碼時,我們的開發人員產生了疑問:
cnn.Open "Provider=SQLOLEDB.1;
Persist Security Info=False;User ID=sa;
Initial Catalog=freemail;Data Source=svr;ConnectionTimeout=10", "", "", -1
sql = "select * from users"
Set rs = cnn.Execute(sql)
執行這段代碼時,在SQL Server Profiler中看到,每個sql語句執行之前都會有一個Audit Login事件。而Audit Login事件的解釋是:“收集自跟蹤啟動後發生的所有新的連接事件,例如客戶端請求連接到運行 Microsoft® SQL Server™ 實例的服務器”。也就是說,用Connection對象連接SQL Server之後,每次執行sql語句時仍然會重新建立一次連接,即使用的是同一個Connection?!
建立連接的事件探查記錄(按時間順序)為:
EventClass
Text Data
TraceStart
Audit Login
(第一次連接)
-- network protocol: LPC
set quoted_identifIEr on
set implicit_transactions off
set cursor_close_on_commit off
set ansi_warnings on
set ansi_padding on
set concat_null_yIElds_null on
set language 簡體中文
set dateformat ymd
set datefirst 7
SQL:Stm tStarting
Select * from users
Audit Login
(第2次連接)
-- network protocol: LPC
set quoted_identifIEr on
set implicit_transactions off…略
SQL:Stm tStarting
Select * from users
Audit Login
(第3次連接)
-- network protocol: LPC
set quoted_identifIEr on
set implicit_transactions off…略
SQL:S
Select * from users
Audit Logout
Audit Logout
Audit Logout
TraceStop
而如果每句cnn.Execute後面加上rs.close(),則每個execute之前不會有Audit Login事件,而是連續的3個SQL:StmtStarting事件。
這樣頻繁建立物理連接,是否會影響性能?照例說應該重用同一個連接才對呀?
這種情況叫做隱式登錄。
當set一個ADO.Recordset對象接收ADO.Connection.Execute返回的記錄集時,就會出現隱式登錄,再次和數據庫服務器建立一次物理連接,而且這個連接還沒有辦法重用,也不能池化。
這個的原因是:
Because the SQL Server OLE DB provider doesn't permit more than one set of results to be pending on a connection where the results are being returned by means of a forward-only, read-only (default-resultset) cursor, the provider needs to create an additional SQL Server connection to execute a second command on the connection. The provider will only do this implicitly if the Data Source property DBPROP_MULTIPLECONNECTIONS is set to VARIANT_TRUE.
可以參考微軟的KB文檔:
aspx?scid=kb;EN-GB;q271128&GSSNB=1">http://support.microsoft.com/default.ASPx?scid=kb;EN-GB;q271128&GSSNB=1
《PRB: Implicit Connections Created by the SQL Server OLE DB Provider (SQLOLEDB) Are Not Pooled》
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim rs2 As New ADODB.Recordset
cn.open ..........
rs.ActiveConnection = cn
rs.Open "select * from orders"
rs.CursorType = adOpenStatic
rs2.ActiveConnection = cn
rs2.Open "select * from orders"
看來,確實如微軟所說的,只有接收默認的記錄集時才會發生隱式連接。如果設置ADO.Recordset為其它類型,如靜態集,就不會發生這個問題。
當然,默認的記錄集的屬性forward-only、read-only情況執行速度最快。
Writen by [email protected]
本文檔所包含的信息代表了在發布之日,ZhengYun 對所討論問題的當前看法,Zhengyun 不保證所給信息在發布之日以後的准確性。