驱动程序管理器连接池
连接池使应用程序能够使用来自不需要为每个用途重新建立的连接池中的连接。 创建并将连接放置在池中后,应用程序可以重复使用该连接,而无需执行完整的连接过程。
使用共用连接可能会导致性能显著提升,因为应用程序可以节省进行连接所涉及的开销。 对于通过网络连接的中间层应用程序,或对于重复连接和断开连接的应用程序(例如 Internet 应用程序)而言,这尤其重要。
除了性能提升之外,连接池体系结构还允许单个进程中的多个组件使用环境及其关联的连接。 这意味着同一进程中的独立组件可以相互交互,而无需相互识别彼此。 连接池中的连接可由多个组件反复使用。
注意
连接池可由显示 ODBC 2.x 行为的 ODBC 应用程序使用,只要应用程序可以调用 SQLSetEnvAttr。 使用连接池时,应用程序不得执行更改数据库或数据库的上下文的 SQL 语句,例如更改<数据库名称>,从而更改数据源使用的目录。
ODBC 驱动程序必须完全线程安全,并且连接不得具有线程关联来支持连接池。 这意味着驱动程序可以随时处理任何线程上的调用,并且能够在一个线程上进行连接,在另一个线程上使用连接,并在第三个线程上断开连接。
连接池由驱动程序管理器进行维护。 当应用程序调用 SQLConnect 或 SQLDriverConnect 时,将从池中提取连接,当应用程序调用 SQLDisconnect 时会返回到池。 池的大小会根据请求的资源分配动态增长。 它根据非活动超时而收缩:如果连接在一段时间内处于非活动状态(它尚未在连接中使用),则会从池中删除。 池的大小仅受内存约束和服务器上的限制而限制。
驱动程序管理器根据 SQLConnect 或 SQLDriverConnect 传递的参数以及分配连接后设置的连接属性来确定池中的特定连接是否应使用。
当驱动程序管理器汇总连接时,它需要能够确定连接在发出连接之前是否仍在工作。 否则,每当发生暂时性网络故障时,驱动程序管理器都会继续向应用程序发出死连接。 在 ODBC 3*.x* 中定义了新的连接属性:SQL_ATTR_CONNECTION_DEAD。 这是返回 SQL_CD_TRUE 或 SQL_CD_FALSE 的只读连接属性。 值 SQL_CD_TRUE 表示连接已丢失,而值 SQL_CD_FALSE 表示连接仍处于活动状态。 (符合早期版本的 ODBC 的驱动程序也可以支持此属性。)
驱动程序必须有效地执行此选项,否则其将减损连接池性能。 具体而言,获取此连接属性的调用不应导致服务器往返。 相反,驱动程序应只返回连接的最近已知状态。 如果最后一次访问服务器失败,则连接将失效,如果最后一次访问成功,则连接不会失效。
注解
如果连接已丢失(通过 SQL_ATTR_CONNECTION_DEAD 报告),ODBC 驱动程序管理器将通过调用驱动程序中的 SSQLDisconnect 来销毁该连接。 新的连接请求可能无法在池中找到可使用的连接。 最终,驱动程序管理器可能会假设池为空,从而建立新的连接。
要使用连接池,应用程序将执行以下步骤:
通过调用 SQLSetEnvAttr 将 SQL_ATTR_CONNECTION_POOLING 环境属性设置为 SQL_CP_ONE_PER_DRIVER 或 SQL_CP_ONE_PER_HENV 来启用连接池。 必须在应用程序分配要在其中启用连接池的共享环境之前进行此调用。 SQLSetEnvAttr 调用中的环境句柄应设置为 null,这使得 SQL_ATTR_CONNECTION_POOLING 成为进程级属性。 如果属性设置为 SQL_CP_ONE_PER_DRIVER,则每个驱动程序都支持单个连接池。 如果应用程序使用很多驱动程序和较少环境,则可能更高效,因为可能需要较少的比较。 如果设置为 SQL_CP_ONE_PER_HENV,则每个环境都支持单个连接池。 如果应用程序使用很多环境和较少驱动程序,则可能更高效,因为可能需要较少的比较。 通过将 SQL_ATTR_CONNECTION_POOLING 设置为 SQL_CP_OFF 来禁用连接池。
通过将 HandleType 参数设置为 SQL_HANDLE_ENV 调用 SQLAllocHandle 来分配环境。 此调用分配的环境将是隐式共享环境,因为已启用了连接池。 但是,在此环境中调用具有 HandleType 的 SQL_HANDLE_DBC 的 SQLAllocHandle 之前,不会确定要使用的环境。
通过将 InputHandle 设置为 SQL_HANDLE_DBC 并将 InputHandle 设置为为连接池分配的环境句柄来调用 SQLAllocHandle,从而分配连接。 驱动程序管理器尝试查找与应用程序设置的环境属性所匹配的现有环境。 如果不存在此类环境,则会使用引用计数 1(由驱动程序管理器维护)创建一个环境。 如果找到匹配的共享环境,则会将环境返回到应用程序,并且其引用计数会递增。 (要使用的实际连接由驱动程序管理器确定,直到调用 SQLConnect 或 SQLDriverConnect 时)。
调用 SQLConnect 或 SQLDriverConnect 以建立连接。 驱动程序管理器使用对 SQLConnect 的调用中的连接选项(或者对 SQLDriverConnect 的调用中的连接关键字)以及连接分配后设置的连接属性,以确定应使用池中的哪个连接。
注意
请求的连接如何与共用连接匹配,取决于 SQL_ATTR_CP_MATCH 环境属性。 有关更多信息,请参阅 SQLSetEnvAttr。
使用连接池的 ODBC 应用程序应在应用程序初始化期间调用 CoInitializeEx,并在应用程序关闭时调用 CoUninitialize。
使用连接完成后调用 SQLDisconnect。 连接将返回到连接池,并且可供重复使用。
有关深入讨论,请参阅 Microsoft 数据访问组件中的池。
连接池的注意事项
使用 SQL 命令(而不是通过 ODBC API)执行以下任何操作,可能会影响连接的状态,并在连接池处于活动状态时导致意外问题:
打开连接并更改默认数据库。
使用 SET 语句更改任何可配置选项(包括 SET ROWCOUNT、ANSI_NULL、IMPLICIT_TRANSACTIONS、SHOWPLAN、STATISTICS、TEXTSIZE 和 DATEFORMAT)。
创建临时表和存储过程。
如果在 ODBC API 之外执行上述任何操作,则使用连接的下一位用户将自动继承以前的设置、表或过程。
注意
不期望某些设置处于连接状态。 应始终在应用程序中设置连接状态,并确保应用程序移除了任何未使用的连接池设置。
识别驱动程序的连接池
从 Windows 8 开始,ODBC 驱动程序便可以更有效地使用池中的连接。 有关详细信息,请参阅识别驱动程序的连接池。