防止
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
zhengyun@tomosoft.com
本文档所包含的信息代表了在发布之日,
ZhengYun
对所讨论问题的当前看法,
Zhengyun
不保证所给信息在发布之日以后的准确性。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=12694