代码之家  ›  专栏  ›  技术社区  ›  Ian Boyd

如何禁止oledb打开其他隐式非池连接?

  •  1
  • Ian Boyd  · 技术社区  · 6 年前

    oledb有一个隐蔽的特性,如果当前连接很忙,它会悄悄地打开更多的数据库连接。

    • 这些事情发生在你不知情的情况下
    • 并且它们不会从连接池中获取或返回到连接池中

    使用SQL Server 2005 ,微软推出了一项功能,其中一个连接可以支持 ; 这样,您就可以在一段时间内正式激活多个记录集 单一的 连接。但他们指出,启用它是一件棘手的事情,这就是为什么它从beta2版开始就被选择加入。

    秘密联系?真的?

    微软 notes this behavior:

    将ADO与sqlserver本机客户端结合使用

    因为隐式连接没有在oledb连接池中汇集,这将导致额外的开销。使用SQLServer本机客户端OLEDB提供程序公开的MARS功能,可以在一个连接上获得多个活动结果。

    约翰C。戈登 in the Microsoft forums: ( archive )

    在一份报告中也提到了这一点 MARS announcement blog entry: archive

    第二个结果集是每次打开时都使用一个新连接。这显然有一些开销(而且事实证明,额外的连接不是池化的,所以每次开销都是用于一个完整的服务器连接网络协议交换)。这是SQLOLEDB和SQL本机客户端(OLEDB)的默认行为当主连接忙于处理默认结果集时,会生成新的隐式连接。

    额外的闲聊

    • oledb是一个低级的、复杂的API
    • ADO是oledb的简化包装器

    怎么关掉?

    这种自动创建辅助连接的方式显然不好。如果SQLServerODBC驱动程序不能做到这一点,那就太不好了(因为这是OLEDB内部的一项功能,而且是免费提供给SQLServerOLEDB驱动程序的)。它不是ODBC内部的一个功能)。

    我想确定我没有这么做。为此我 希望 驱动程序在我的代码中的某个点抛出错误,我不小心尝试这样做。

    0 回复  |  直到 6 年前
        1
  •  0
  •   Ian Boyd    3 年前

    解决方案是禁用OLEB将在您背后打开多个连接的功能。

    你可以设置 Multiple Connections ADO连接的属性 false 防止它在主连接忙于处理结果集时隐式打开第二个连接。

    //Set Connection.Properties["Multiple Connections"] = false
    for int i = 0 to Connection.Properties.Count-1
    {
        Property prop = Connection.Properties.Item[i];
        if (prop.Name == "Multiple Connections")
        {
            prop.Value = false;
            break;
        }
    }
    

    请注意,关闭打开第二个连接的功能意味着 工作会突然开始 fail 带着错误 “对象已打开”

    奥德伯格

    //
    // MessageId: DB_E_OBJECTOPEN
    //
    // MessageText:
    //
    //  An object was open
    //
    #define DB_E_OBJECTOPEN                  ((HRESULT)0x80040E05L)
    

    警告

    这个 多个连接 属性不适用于ODBC OLEDB驱动程序(MSDASQL)或Active Directory驱动程序(ADSO对象)

    事实上,他们的行为 查询 “为” 多个连接 “财产 这个 ADSO对象 (active directory)提供程序使其抛出

    “在集合中找不到项”

    以后发生异常时 跑步 选择查询。

    prop.Value = false;
    

    仍然会导致错误。

    询问 对于一个不存在的导致它失败的属性。所以我们 迭代