Desenvolvimento um reconhecimento de pool de conexão em um driver ODBC
Este tópico discute os detalhes do desenvolvimento de um driver ODBC que contém informações sobre como o driver deve fornecer serviços de pool de conexões.
Habilitar o pool de conexões com reconhecimento de driver
Um driver deve implementar as seguintes funções da SPI (interface do provedor de serviços) ODBC:
SQLSetConnectAttrForDbcInfo
SQLSetConnectInfo
SQLSetDriverConnectInfo
SQLGetPoolID
SQLRateConnection
SQLPoolConnect
SQLCleanupConnectionPoolID
Consulte Referência da SPI (Interface do Provedor de Serviços) ODBC para obter mais informações.
Um driver também deve implementar as seguintes funções existentes para que o pool com reconhecimento de driver possa ser habilitado:
Função | Funcionalidade adicionada |
---|---|
SQLAllocHandle SQLFreeHandle SQLGetDiagField SQLGetDiagRec |
Suporte ao novo tipo de identificador: SQL_HANDLE_DBC_INFO_TOKEN (consulte a descrição abaixo). |
SQLSetConnectAttr | Suporte ao novo atributo de conexão somente de conjunto: SQL_ATTR_DBC_INFO_TOKEN para redefinir a conexão (consulte a descrição abaixo). |
Observação
Não há suporte para funções preteridas, como SQLError e SQLSetConnectOption para pool de conexões com reconhecimento de driver.
A ID do pool
A ID do pool é uma ID específica do driver com comprimento de ponteiro para representar um grupo específico de conexões que podem ser usadas de forma intercambiável. Dado um conjunto de informações de conexão, um driver deve ser capaz de deduzir rapidamente a ID do pool correspondente.
Por exemplo, a ID do pool deve codificar o nome do servidor e as informações de credencial. No entanto, o nome do banco de dados não é necessário, pois um driver pode reutilizar uma conexão e alterar o banco de dados em menos tempo do que a criação de uma nova conexão.
Um driver deve definir um conjunto de atributos-chave, que constituirão a ID do pool. O valor desses atributos de chave pode vir de atributos de conexão, cadeia de conexão e DSN. Caso haja algum conflito nessas fontes, a política de resolução específica do driver existente deve ser usada para compatibilidade com versões anteriores.
O Gerenciador de Driver usará um pool diferente para diferentes IDs de pool. Todas as conexões no mesmo pool são reutilizáveis. O Gerenciador de Driver nunca reutilizará uma conexão com uma ID de pool diferente.
Portanto, os drivers devem atribuir uma ID de pool exclusiva a cada grupo de conexões com o mesmo valor nos atributos de chave definidos. Se um driver usar a mesma ID de pool para duas conexões com valores diferentes em seus atributos de chave, o Gerenciador de Driver ainda as colocará no mesmo pool (o Gerenciador de Driver desconhece os atributos de chave específicos do driver). Isso significa que o driver precisará informar ao Gerenciador de Driver que uma conexão com um conjunto diferente de atributos de chave não é reutilizável na Função SQLRateConnection. Isso pode diminuir o desempenho e não é recomendado.
O Gerenciador de Driver não reutilizará uma conexão alocada de outro ambiente de driver, mesmo que todas as informações de conexão sejam correspondentes. O Gerenciador de Driver usará um pool diferente para ambientes diferentes, mesmo quando as conexões tiverem a mesma ID do pool. Portanto, a ID do pool é local para seu ambiente de driver.
A função para obter a ID do pool do driver é a Função SQLGetPoolID.
A classificação de conexão
Em comparação com o estabelecimento de uma nova conexão, você pode obter melhor desempenho redefinindo algumas informações de conexão (como DATABASE) em uma conexão em pool. Portanto, talvez não convenha que o nome do banco de dados esteja em seu conjunto de atributos de chave. Caso contrário, você poderá ter um pool separado para cada banco de dados, o que pode não ser adequado em aplicativos de camada intermediária, em que os clientes usam diversas cadeias de conexão diferentes.
Sempre que reutilizar uma conexão que tem alguma incompatibilidade de atributos, você deverá redefinir os atributos incompatíveis com base na nova solicitação do aplicativo, para que a conexão retornada seja idêntica à solicitação do aplicativo (consulte a discussão sobre o atributo SQL_ATTR_DBC_INFO_TOKEN na Função SQLSetConnectAttr). No entanto, a redefinição desses atributos pode diminuir o desempenho. Por exemplo, a redefinição de um banco de dados requer uma chamada de rede para o servidor. Portanto, reutilize uma conexão que seja perfeitamente compatível, se houver alguma disponível.
Uma função de classificação no driver pode avaliar uma conexão existente com uma nova solicitação de conexão. Por exemplo, a função de classificação do driver pode determinar:
Se a conexão existente corresponde perfeitamente à solicitação.
Se há apenas algumas incompatibilidades insignificantes, como tempo limite de conexão, que não exigem comunicação com o servidor para serem redefinidas.
Se há alguns atributos incompatíveis que exijam uma comunicação com o servidor para serem redefinidos, mas ainda assim resultem em melhor desempenho do que o estabelecimento de uma nova conexão.
Se a incompatibilidade ocorreu para um atributo que leva muito tempo para ser redefinido (o desenvolvedor do driver pode considerar a adição desse atributo ao conjunto de atributos de chave, que é usado para gerar a ID do pool).
É possível uma pontuação entre 0 e 100, em que 0 significa não reutilizar e 100 significa corresponder perfeitamente. SQLRateConnection é a função para classificar uma conexão.
Novo identificador ODBC, SQL_HANDLE_DBC_INFO_TOKEN
Para dar suporte ao pool de conexões com reconhecimento de driver, o driver precisa de informações de conexão para calcular a ID do pool. O driver também precisa de informações de conexão para comparar novas solicitações de conexão com conexões no pool. Sempre que nenhuma conexão no pool puder ser reutilizada, o driver deverá estabelecer uma nova conexão, exigindo, assim, informações de conexão.
Como as informações de conexão podem vir de diversas fontes (cadeia de conexão, atributos de conexão e DSN), o driver pode precisar analisar a cadeia de conexão e resolver o conflito entre essas fontes em cada uma das chamadas de função acima.
Portanto, um novo identificador ODBC é introduzido: SQL_HANDLE_DBC_INFO_TOKEN. Com SQL_HANDLE_DBC_INFO_TOKEN, um driver não precisa analisar a cadeia de conexão e resolver conflitos nas informações de conexão mais de uma vez. Como essa é uma estrutura de dados específica do driver, o driver pode armazenar dados como informações de conexão ou ID do pool.
Esse identificador é usado apenas como uma interface entre o Gerenciador de Driver e o driver. Um aplicativo não pode alocar esse identificador diretamente.
O identificador pai desse identificador é do tipo SQL_HANDLE_ENV, o que significa que o driver pode obter as informações de ambiente do identificador HENV durante a resolução de informações de conexão.
Sempre que receber uma nova solicitação de conexão, o Gerenciador de Driver alocará um identificador do tipo SQL_HANDLE_DBC_INFO_TOKEN para armazenar informações de conexão, após confirmar que o driver dá suporte ao reconhecimento do pool de conexões. Quando terminar de usar o identificador (mas antes de retornar alguns códigos de retorno diferentes de SQL_STILL_EXECUTING de SQLDriverConnect ou SQLConnect), o Gerenciador de Driver liberará o identificador. Portanto, o identificador é criado após a chamada SQLAllocHandle e destruído após a chamada SQLFreeHandle. O Gerenciador de Driver garante que o identificador será liberado antes de liberar seu HENV associado SQLDriverConnect ou SQLConnect retornar um erro).
O driver deve modificar as seguintes funções para aceitar o novo tipo de identificador SQL_HANDLE_DBC_INFO_TOKEN:
O Gerenciador de Driver garante que vários threads não usem o mesmo identificador SQL_HANDLE_DBC_INFO_TOKEN simultaneamente. Portanto, o modelo de sincronização desse identificador pode ser muito simples no driver. O Gerenciador de Driver não realizará um bloqueio de ambiente antes de alocar e liberar SQL_HANDLE_DBC_INFO_TOKEN.
SQLAllocHandle e SQLFreeHandle ddo Gerenciador de Driver não aceitarão esse novo tipo de identificador.
SQL_HANDLE_DBC_INFO_TOKEN pode conter informações confidenciais, como credenciais. Portanto, um driver deve limpar com segurança o buffer de memória (usando SecureZeroMemory) que contém as informações confidenciais antes de liberar esse identificador com SQLFreeHandle. Sempre que o identificador de ambiente de um aplicativo for fechado, todos os pools de conexões associados serão fechados.
Algoritmo de classificação do pool de conexões do Gerenciador de Driver
Esta seção discute o algoritmo de classificação para o pool de conexões do Gerenciador de Driver. Os desenvolvedores de drivers podem implementar o mesmo algoritmo para compatibilidade com versões anteriores. Esse algoritmo pode não ser o melhor. Você deve refinar esse algoritmo com base em sua implementação (caso contrário, não há razão para implementar esse recurso).
O Gerenciador de Driver retornará uma classificação integral de 0 a 100 para cada conexão do pool. 0 significa que a conexão não pode ser reutilizada e 100 indica uma correspondência perfeita. Suponha que a solicitação de conexão seja denominada hRequest e a conexão existente do pool seja denominada hCandidate. Se qualquer uma das condições a seguir for falsa, a conexão em pool hCandidate não poderá ser reutilizada para hRequest (o Gerenciador de Driver atribuirá uma classificação de 0).
hCandidate e hRequest vêm da API UNICODE (como SQLDriverConnectW) ou da API ANSI (como SQLDriverConnectA). (Os drivers UNICODE podem ter comportamento diferente de acordo com a API ANSI e a API UNICODE (consulte o atributo de conexão SQL_ATTR_ANSI_APLICATIVO).)
hCandidate e hRequest são criados pela mesma função; SQLDriverConnect ou SQLConnect.
A cadeia de conexão usada para abrir hCandidate deve ser igual a hRequest, quando SQLDriverConnect é usado.
O ServerName (ou DSN), o nome de usuário e a senha usados para abrir hCandidate devem ser os mesmos usados para abrir hRequest quando SQLConnect é usado.
O SID (identificador de segurança) do thread atual deve ser o mesmo que o SID usado para abrir o hCandidate.
Para drivers cuja inscrição e cancelamento de inscrição são caros (consulte a discussão sobre SQL_DTC_TRANSITION_COST em SQLConnect), a reutilização de hRequest não deve exigir uma inscrição ou cancelamento de inscrição extra.
A tabela a seguir mostra a atribuição de pontuação para diferentes cenários.
Comparação de atributos de conexão entre a conexão em pool e a solicitação | Sem inscrição/cancelamento de inscrição | Exigir inscrição/cancelamento de inscrição extra |
---|---|---|
O catálogo (SQL_ATTR_CURRENT_CATALOG) é diferente | 60 | 50 |
Alguns atributos de conexão são diferentes, mas o catálogo é o mesmo | 90 | 70 |
Todos os atributos de conexão são perfeitamente correspondentes | 100 | 80 |
Diagrama de sequências
Este diagrama de sequência mostra o mecanismo básico de agrupamento descrito neste tópico. Ele mostra apenas o uso de SQLDriverConnect, mas o caso de SQLConnect é semelhante.
Diagrama de estado
Este diagrama de estado mostra o objeto token de informações de conexão, descrito neste tópico. O diagrama mostra apenas SQLDriverConnect, mas o caso de SQLConnect é semelhante. Como o Gerenciador de Driver pode precisar tratar erros a qualquer momento, o Gerenciador de Driver pode chamar SQLFreeHandle para qualquer estado.
Confira também
Pool de conexões com reconhecimento de driver
Referência da SPI (Interface do Provedor de Serviços) do ODBC