Поделиться через


Разработка поддержки Connection-Pool в драйвере ODBC

В этом разделе рассматриваются сведения о разработке драйвера ODBC, содержащего сведения о том, как драйвер должен предоставлять службы пула подключений.

Включение пула подключений, учитывающего особенности драйвера

Драйвер должен реализовать следующие функции интерфейса поставщика служб ODBC (SPI):

  • SQLSetConnectAttrForDbcInfo

  • SQLSetConnectInfo

  • SQLSetDriverConnectInfo

  • SQLGetPoolID

  • SQLRateConnection

  • SQLPoolConnect

  • SQLCleanupConnectionPoolID

Дополнительные сведения см. в справочнике по интерфейсу поставщика услуг ODBC (SPI ).

Драйвер также должен реализовать следующие существующие функции, чтобы включить пул с поддержкой драйверов:

Функция Добавлена функциональность
SQLAllocHandle

SQLFreeHandle

SQLGetDiagField

SQLGetDiagRec
Поддержка нового типа дескриптора: SQL_HANDLE_DBC_INFO_TOKEN (см. описание ниже).
SQLSetConnectAttr Поддержка нового атрибута подключения, который можно только устанавливать: SQL_ATTR_DBC_INFO_TOKEN для сброса соединения (см. описание ниже).

Замечание

Устаревшие функции, такие как SQLError и SQLSetConnectOption , не поддерживаются для пула подключений с поддержкой драйверов.

Идентификатор пула

Идентификатор пула — это специфичный для драйвера идентификатор длины указателя, представляющий определенную группу подключений, которые можно использовать взаимозаменяемо. Учитывая набор сведений о подключении, драйвер должен быстро выводить соответствующий идентификатор пула.

Например, идентификатор пула должен кодировать имя сервера и учетные данные. Однако имя базы данных не требуется, так как драйвер может повторно использовать подключение, а затем изменить базу данных в меньшее время, чем создать новое подключение.

Драйвер должен определить набор ключевых атрибутов, который будет содержать идентификатор пула. Значение этих ключевых атрибутов может поступать из атрибутов подключения, строки подключения и DSN. Если в этих источниках существуют конфликты, существующая политика разрешения для конкретного драйвера должна использоваться для обратной совместимости.

Диспетчер драйверов будет использовать другой пул для различных идентификаторов пула. Все подключения в одном пуле можно использовать повторно. Диспетчер драйверов никогда не будет повторно использовать подключение с другим идентификатором пула.

Поэтому драйверы должны назначать уникальный идентификатор пула для каждой группы подключений с одинаковым значением в определенных ключевых атрибутах. Если драйвер использует один и тот же идентификатор пула для двух подключений с разными значениями в своих ключевых атрибутах, диспетчер драйверов по-прежнему помещает их в один пул (диспетчер драйверов ничего не знает об атрибутах ключа для конкретного драйвера). Это означает, что драйверу потребуется сообщить диспетчеру драйверов, что соединение с другим набором ключевых атрибутов не используется повторно в функции SQLRateConnection. Это может снизить производительность, и это не рекомендуется.

Диспетчер драйверов не будет повторно использовать подключение, выделенное из другой среды драйвера, даже если все сведения о подключении совпадают. Диспетчер драйверов будет использовать другой пул для разных сред, даже если подключения имеют один и тот же идентификатор пула. Таким образом, идентификатор пула является локальным для среды драйвера.

Функция получения идентификатора пула от драйвера — функция SQLGetPoolID.

Оценка подключения

По сравнению с установлением нового подключения, можно повысить производительность, сбросив некоторые параметры подключения (например, DATABASE) в пуле подключений. Таким образом, возможно, имя базы данных не должно находиться в наборе ключевых атрибутов. В противном случае для каждой базы данных может быть отдельный пул, что может не подходить в приложениях среднего уровня, где пользователи используют различные строки подключения.

При повторном использовании соединения с некоторыми несоответствиями атрибутов следует сбросить несовпаденные атрибуты на основе нового запроса приложения, чтобы возвращенное подключение было идентично запросу приложения (см. обсуждение атрибута SQL_ATTR_DBC_INFO_TOKEN в функции SQLSetConnectAttr). Однако сброс этих атрибутов может привести к снижению производительности. Например, для сброса базы данных требуется сетевой вызов к серверу. Поэтому повторно используйте идеально подходящее соединение, если оно доступно.

Функция оценки в драйвере может оценить существующее соединение с новым запросом на подключение. Например, функция оценки драйвера может определить следующее:

  • Если существующее подключение идеально соответствует запросу.

  • Если существует только некоторые незначительные несоответствия, такие как время ожидания подключения, которые не требуют связи с сервером для сброса.

  • Если имеются несоответствующие атрибуты, которые требуют обмена данными с сервером для сброса, это все же приведет к лучшей производительности по сравнению с установкой нового подключения.

  • Если произошло несоответствие для атрибута, сброс которого занимает много времени, разработчик драйвера может рассмотреть возможность добавления этого атрибута в набор ключевых атрибутов, используемых для создания идентификатора пула.

Оценка от 0 до 100 возможна, где 0 означает не использовать повторно и 100 означает полностью соответствует. SQLRateConnection — это функция для оценки соединения.

Новый дескриптор ODBC — SQL_HANDLE_DBC_INFO_TOKEN

Для поддержки пула подключений с поддержкой драйверов драйверу требуется информация о подключении для вычисления идентификатора пула. Драйвер также нуждается в сведениях о подключении для сравнения новых запросов подключения с существующими подключениями в пуле. Всякий раз, когда подключение в пуле невозможно повторно использовать, драйвер должен установить новое подключение, поэтому требуется информация о подключении.

Так как сведения о подключении могут поступать из нескольких источников (строка подключения, атрибуты подключения и DSN), драйвер может потребоваться проанализировать строку подключения и устранить конфликт между этими источниками в каждом из приведенных выше вызовов функции.

Таким образом, появился новый дескриптор ODBC: SQL_HANDLE_DBC_INFO_TOKEN. При использовании SQL_HANDLE_DBC_INFO_TOKEN драйвер не должен анализировать строку подключения и разрешать конфликты в сведениях о подключении более одного раза. Так как это структура данных для конкретного драйвера, драйвер может хранить такие данные, как сведения о подключении или идентификатор пула.

Эта рукоять используется исключительно как интерфейс между диспетчером драйверов и драйвером. Приложение не может напрямую выделить этот дескриптор.

Родительский дескриптор этого дескриптора имеет тип SQL_HANDLE_ENV, что означает, что драйвер может получить сведения о среде из дескриптора HENV в процессе разрешения информации о подключении.

Когда диспетчер драйверов получает новый запрос на подключение, он выделяет дескриптор типа SQL_HANDLE_DBC_INFO_TOKEN для хранения сведений о подключении, после подтверждения того, что драйвер поддерживает работу с пулом подключений. После завершения использования дескриптора (но перед возвратом некоторых кодов возврата, отличных от SQL_STILL_EXECUTING из SQLDriverConnect или SQLConnect), диспетчер драйверов освободит дескриптор. Поэтому дескриптор создается после вызова SQLAllocHandle и уничтожается после вызова SQLFreeHandle. Диспетчер драйверов гарантирует, что дескриптор будет освобожден перед освобождением связанного HENV (когда SQLDriverConnect или SQLConnect возвращает ошибку).

Драйвер должен изменить следующие функции, чтобы принять новый тип дескриптора SQL_HANDLE_DBC_INFO_TOKEN:

  1. SQLAllocHandle

  2. SQLFreeHandle

  3. SQLGetDiagField

  4. SQLGetDiagRec

Диспетчер драйверов гарантирует, что несколько потоков одновременно не будут использовать один и тот же дескриптор SQL_HANDLE_DBC_INFO_TOKEN. Поэтому модель синхронизации этого хендла может быть очень простой внутри драйвера. Диспетчер драйверов не будет выполнять блокировку окружения перед выделением и освобождением SQL_HANDLE_DBC_INFO_TOKEN.

SqlAllocHandle и SQLFreeHandle диспетчера драйверов не принимают этот новый тип дескриптора.

SQL_HANDLE_DBC_INFO_TOKEN может содержать конфиденциальную информацию, например учетные данные. Таким образом, драйвер должен безопасно очистить буфер памяти (с помощью SecureZeroMemory), в котором содержится конфиденциальная информация, прежде чем освободить этот дескриптор с помощью SQLFreeHandle. При закрытии дескриптора окружения приложения все связанные пулы соединений будут закрыты.

Алгоритм оценки пула соединений менеджера драйверов

В этом разделе описывается алгоритм ранжирования для пула подключений Диспетчера драйверов. Разработчики драйверов могут реализовать тот же алгоритм для обратной совместимости. Этот алгоритм может быть не лучшим. Этот алгоритм необходимо доработать на основе вашей реализации (в противном случае нет смысла реализовывать эту функцию).

Диспетчер драйверов возвращает целочисленную оценку от 0 до 100 для каждого подключения из пула. 0 означает, что подключение не может быть повторно использовано, и 100 указывает на идеальное соответствие. Предположим, что запрос на подключение называется hRequest, а существующее подключение из пула называется hCandidate. Если хоть одно из следующих условий ложно, подключение в пуле hCandidate нельзя повторно использовать для hRequest (управляющий драйверами присвоит рейтинг 0).

  • hCandidate и hRequest оба приходят из API ЮНИКОДа (например, SQLDriverConnectW) или API ANSI (например, SQLDriverConnectA). (Драйверы ЮНИКОД могут выполнять различные действия с помощью API ANSI и API ЮНИКОДа (см. атрибут подключения SQL_ATTR_ANSI_APP).)

  • hCandidate и hRequest создаются той же функцией; ЛИБО SQLDriverConnect, либо SQLConnect.

  • Строка подключения, используемая для открытия hCandidate, должна совпадать с hRequest при использовании SQLDriverConnect.

  • Имя сервера (или DSN), имя пользователя и пароль, используемые для открытия hCandidate, должны использоваться для открытия hRequest при использовании SQLConnect.

  • Идентификатор безопасности (SID) текущего потока должен совпадать с идентификатором безопасности, используемым для открытия hCandidate.

  • Для драйвера, дорогого для подключения и отключения (см. обсуждение SQL_DTC_TRANSITION_COST в SQLConnect), повторное использование hRequest не должно требовать дополнительного подключения или отключения.

В следующей таблице показано назначение оценки для различных сценариев.

Сравнение атрибутов подключения между подключением в пуле и запросом Нет присоединения / отмены учета Требовать дополнительную регистрацию / отмену регистрации
Каталог (SQL_ATTR_CURRENT_CATALOG) отличается 60 50
Некоторые атрибуты подключения отличаются, но каталог совпадает 90 70
Все атрибуты подключения идеально совпадают 100 80

Схема последовательности

На этой схеме последовательности показан базовый механизм объединения, описанный в этом разделе. Он показывает только использование SQLDriverConnect , но вариант SQLConnect аналогичен.

Схема последовательности

Схема состояния

На этой схеме состояния показан объект маркера сведений о подключении, описанный в этом разделе. На схеме показан только SQLDriverConnect , но пример SQLConnect аналогичен. Так как диспетчер драйверов может в любое время обрабатывать ошибки, диспетчер драйверов может вызывать SQLFreeHandle для любого состояния.

Схема состояния

См. также

Организация пулов соединений с учетом драйвера
Справочник по интерфейсу поставщика служб ODBC (SPI)