防止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 不做任何明示或默示的保证。