• 防止ADO连接SQL Server时的隐式连接


    问题陈述:

    数据库服务器: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文档:
    《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情况执行速度最快。
  • 相关阅读:
    2018陕西省高三教学质量检测三参考答案图片版
    2018年宝鸡市三检理科数学题目解答
    2018年宝鸡市三检文科数学题目解答
    构建flutter环境并实现属于我们的hello world
    关于react-native项目在MacBookPro环境下打包成IPA
    关于react-native在MacBookPro环境下的安装
    react-native---rn中的修饰组件(TouchableHightlight、TouchableOpacity、TouchableNativeFeedback等)
    px转换成bp单位的工具函数
    跟我一起使用android Studio打包react-native项目的APK
    undefined is not an object(evaluating '_react3.default.PropTypes.shape)
  • 原文地址:https://www.cnblogs.com/MaxIE/p/950761.html
Copyright © 2020-2023  润新知