防止ADO連接SQL Server時的隱式連接
2024-08-31 00:48:28
供稿:網友
 
注冊會員,創建你的web開發資料庫,防止ado連接sql server時的隱式連接
report date:   2002/9
prepared by:     鄭            昀
article last modified on 2002-9
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)
      set rs2 = cnn.execute(sql)
      set rs3 = 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 ansi_nulls 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:stm tstarting
select * from users
audit logout
 
audit logout
 
audit logout
 
tracestop
 
 
而如果每句cnn.execute后面加上rs.close(),則每個execute之前不會有audit login事件,而是連續的3個sql:stmtstarting事件。
這樣頻繁建立物理連接,是否會影響性能?照例說應該重用同一個連接才對呀?
cause:
這種情況叫做隱式登錄。
當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文檔:
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》
 
【不會重復建立數據庫連接的代碼片斷】:
 
通過改變ado.recordset的屬性避免隱式登錄 
dim cn as new adodb.connection
dim rs as new adodb.recordset
dim rs2 as new adodb.recordset
cn.open ..........
 
rs.cursortype = adopenstatic
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 不保證所給信息在發布之日以后的準確性。 
本文檔僅供參考。對本文檔中的信息,zhengyun 不做任何明示或默示的保證。