Sviluppo del rilevamento di pool di connessioni in un driver ODBC

In questo argomento vengono illustrati i dettagli dello sviluppo di un driver ODBC che contiene informazioni sul modo in cui il driver deve fornire servizi di pool di connessioni.

Pool di connessioni compatibile con il driver

Un driver deve implementare le funzioni SPI (Service Provider Interface, interfaccia del provider di servizi) ODBC seguenti:

  • SQLSetConnectAttrForDbcInfo

  • SQLSetConnectInfo

  • SQLSetDriverConnectInfo

  • SQLGetPoolID

  • SQLRateConnection

  • SQLPoolConnect

  • Funzione SQLCleanupConnectionPoolID

Per altre informazioni, vedere Riferimento all’interfaccia del provider di servizi (SPI) ODBC.

Un driver deve anche implementare le seguenti funzioni esistenti per poter abilitare il pooling compatibili con il driver:

Funzione Funzionalità aggiunta
SQLAllocHandle

SQLFreeHandle

SQLGetDiagField

SQLGetDiagRec
Supportare il nuovo tipo di handle: SQL_HANDLE_DBC_INFO_TOKEN (vedere la descrizione seguente).
SQLSetConnectAttr Supporta il nuovo attributo di connessione set-only: SQL_ATTR_DBC_INFO_TOKEN per resettare la connessione (vedi la descrizione sotto).

Nota

Le funzioni deprecate, come SQLError e SQLSetConnectOption, non sono supportate per il pooling delle connessioni consapevole del driver.

ID pool

L'ID del pool è un ID specifico del driver con una lunghezza di puntatore per rappresentare un particolare gruppo di connessioni che possono essere utilizzate in modo interscambiabile. Dato un insieme di informazioni sulla connessione, un driver dovrebbe essere in grado di dedurre rapidamente l'ID del pool corrispondente.

Ad esempio, l'ID pool deve codificare il nome del server e le informazioni sulle credenziali. Tuttavia, il nome del database non è necessario perché un driver potrebbe essere in grado di riutilizzare una connessione e quindi modificare il database in meno tempo rispetto alla creazione di una nuova connessione.

Un driver deve definire un set di attributi chiave, che comprenderà l'ID del pool. Il valore di questi attributi chiave può provenire da attributi di connessione, stringa di connessione e DSN. In caso di conflitti in queste origini, è consigliabile usare i criteri di risoluzione specifici del driver esistenti per garantire la compatibilità con le versioni precedenti.

Gestione driver userà un pool diverso per ID pool diversi. Tutte le connessioni nello stesso pool sono riutilizzabili. Gestione driver non riutilizza mai una connessione con un ID pool diverso.

Pertanto, i driver devono assegnare un ID pool univoco per ogni gruppo di connessioni con lo stesso valore negli attributi chiave definiti. Se un driver usa lo stesso ID pool per due connessioni con valori diversi nei relativi attributi chiave, Gestione driver li inserisce nello stesso pool (Gestione driver non è a conoscenza degli attributi chiave specifici del driver). Ciò significa che il driver dovrà segnalare a Gestione driver che una connessione con un set diverso di attributi chiave non è riutilizzabile all'interno della Funzione SQLRateConnection. Ciò può ridurre le prestazioni e questo non è consigliato.

Gestione driver non riutilizzerà una connessione assegnata da un altro ambiente driver anche se tutte le informazioni sulla connessione corrispondono. Gestione driver userà un pool diverso per un ambiente diverso, anche quando le connessioni hanno lo stesso ID pool. Pertanto, l'ID del pool è locale rispetto all'ambiente del driver.

La funzione per ottenere l'ID del pool dal driver è la Funzione SQLGetPoolID.

Valutazione della connessione

Rispetto alla creazione di una nuova connessione, puoi ottenere prestazioni migliori reimpostando alcune informazioni sulla connessione (come DATABASE) in una connessione in pool. Pertanto, potrebbe non essere necessario che il nome del database si trovi nel set di attributi chiave. In caso contrario, è possibile avere un pool separato per ogni database, che potrebbe non essere valido nelle applicazioni di livello intermedio, dove i clienti utilizzano diverse stringhe di connessione.

Ogni volta che si riutilizza una connessione che presenta una mancata corrispondenza di attributi, è necessario reimpostare gli attributi non corrispondenti in base alla nuova richiesta dell'applicazione, in modo che la connessione restituita sia identica alla richiesta dell'applicazione (vedi la discussione sull'attributo SQL_ATTR_DBC_INFO_TOKEN nella Funzione SQLSetConnectAttr). Tuttavia, la reimpostazione di tali attributi può ridurre le prestazioni. Ad esempio, la reimpostazione di un database richiede una chiamata di rete al server. Pertanto, è bene riutilizzare una connessione perfettamente corrispondente, se disponibile.

Una funzione di valutazione nel driver può valutare una connessione esistente con una nuova richiesta di connessione. Ad esempio, la funzione di valutazione del driver può determinare:

  • Se la connessione esistente corrisponde perfettamente alla richiesta.

  • Se sono presenti solo alcuni errori insignificanti, come il timeout della connessione, che non richiedono la comunicazione con il server per essere ripristinati.

  • Se sono presenti degli attributi non corrispondenti che richiedono una comunicazione con il server per essere reimpostati, ma che comunque garantiscono prestazioni migliori rispetto alla creazione di una nuova connessione.

  • Se la mancata corrispondenza si è verificata per un attributo che richiede molto tempo per essere reimpostato (lo sviluppatore del driver può prendere in considerazione l'aggiunta di questo attributo nel set di attributi chiave, che viene utilizzato per generare l'ID del pool).

È possibile ottenere un punteggio compreso tra 0 e 100, dove 0 significa non riutilizzare e 100 significa perfettamente abbinato. SQLRateConnection è la funzione per valutare una connessione.

Nuovo handle ODBC - SQL_HANDLE_DBC_INFO_TOKEN

Per supportare il pooling di connessioni consapevole del driver, quest'ultimo ha bisogno di informazioni sulla connessione per calcolare l'ID del pool. Il driver ha anche bisogno di informazioni sulla connessione per confrontare le nuove richieste di connessione con le connessioni presenti nel pool. Quando nessuna connessione del pool può essere riutilizzata, il driver deve stabilire una nuova connessione, richiedendo quindi le informazioni sulla connessione.

Poiché le informazioni sulla connessione possono provenire da più origini (stringa di connessione, attributi di connessione e DSN), il driver potrebbe dover analizzare la stringa di connessione e risolvere il conflitto tra queste fonti in ogni chiamata di funzione.

Per questo motivo, è stato introdotto un nuovo handle ODBC: SQL_HANDLE_DBC_INFO_TOKEN. Con SQL_HANDLE_DBC_INFO_TOKEN, un driver non deve analizzare la stringa di connessione e risolvere i conflitti nelle informazioni di connessione più di una volta. Poiché si tratta di una struttura dati specifica del driver, quest'ultimo può memorizzare dati come le informazioni sulla connessione o l'ID del pool.

Questo handle viene usato solo come interfaccia tra Gestione driver e driver. Un'applicazione non può assegnare direttamente questo handle.

L'handle padre di questo handle è di tipo SQL_HANDLE_ENV, il che significa che il driver può ottenere le informazioni sull'ambiente dall'handle HENV durante la risoluzione delle informazioni sulla connessione.

Ogni volta che riceve una nuova richiesta di connessione, il Driver Manager alloca un handle di tipo SQL_HANDLE_DBC_INFO_TOKEN per memorizzare le informazioni sulla connessione, dopo aver confermato che il driver supporta la consapevolezza del pool di connessioni. Una volta terminato l'utilizzo dell'handle (ma prima di restituire codici di ritorno diversi da SQL_STILL_EXECUTING da SQLDriverConnect o SQLConnect), il Driver Manager libera l'handle. Pertanto, l'handle viene creato dopo la chiamata SQLAllocHandle ed eliminato definitivamente dopo la chiamata SQLFreeHandle. Gestione driver garantisce che l'handle sarà liberato prima di liberare il suo HENV associato (quando SQLDriverConnect o SQLConnect restituiscono un errore).

Il driver deve modificare le seguenti funzioni per accettare il nuovo tipo di handle SQL_HANDLE_DBC_INFO_TOKEN:

  1. SQLAllocHandle

  2. SQLFreeHandle

  3. SQLGetDiagField

  4. SQLGetDiagRec

Gestione driver garantisce che più thread non utilizzino contemporaneamente lo stesso handle SQL_HANDLE_DBC_INFO_TOKEN. Di conseguenza, il modello di sincronizzazione di questo handle può essere molto semplice all'interno del driver. Gestione driver non eseguirà un blocco ambientale prima di assegnare e liberare SQL_HANDLE_DBC_INFO_TOKEN.

SQLAllocHandle e SQLFreeHandle di Gestione driver non accetteranno questo nuovo tipo di handle.

SQL_HANDLE_DBC_INFO_TOKEN può contenere informazioni riservate, ad esempio le credenziali. Pertanto, il driver deve cancellare in modo sicuro il buffer di memoria (utilizzando SecureZeroMemory) che contiene le informazioni sensibili prima di rilasciare questo handle con SQLFreeHandle. Ogni volta che l'handle dell'ambiente di un'applicazione viene chiuso, tutti i pool di connessioni associati verranno chiusi.

Algoritmo di valutazione del pool di connessioni di Gestione driver

Questa sezione illustra l'algoritmo di valutazione per il pooling delle connessioni di Gestione driver. Gli sviluppatori di driver possono implementare lo stesso algoritmo per garantire la compatibilità con le versioni precedenti. Questo algoritmo potrebbe non essere il migliore. È consigliabile perfezionare questo algoritmo in base all'implementazione (altrimenti non c'è motivo di implementare questa funzione).

Gestione driver restituirà un punteggio integrale da 0 a 100 per ogni connessione del pool. 0 significa che la connessione non può essere riutilizzata e 100 indica un abbinamento perfetto. Supponiamo che la richiesta di connessione si chiami hRequest e che la connessione esistente del pool si chiami hCandidate. Se una delle seguenti condizioni è falsa, la connessione del pool hCandidate non può essere riutilizzata per hRequest (Gestione driver assegnerà un punteggio di 0).

  • hCandidate e hRequest provengono entrambi da API UNICODE (come SQLDriverConnectW) o ANSI (come SQLDriverConnectA) (i driver UNICODE possono comportare comportamenti diversi in base all'API ANSI e all'API UNICODE (vedere l'attributo di connessione SQL_ATTR_ANSI_APP).

  • hCandidate e hRequest vengono creati dalla stessa funzione: SQLDriverConnect o SQLConnect.

  • La stringa di connessione utilizzata per aprire hCandidate deve essere la stessa di hRequest, se si utilizza SQLDriverConnect.

  • Il nome del server (o DSN), il nome utente e la password utilizzati per aprire hCandidate devono essere gli stessi utilizzati per aprire hRequest quando si utilizza SQLConnect.

  • L'identificatore di sicurezza (SID) del thread corrente deve essere lo stesso utilizzato per aprire hCandidate.

  • Per i driver costoso da integrare e rimuovere (vedere ldiscussione su SQL_DTC_TRANSITION_COST in SQLConnect), il riutilizzo di hRequest non deve richiedere un ulteriore integrazione o rimozione.

La tabella seguente mostra l'assegnazione del punteggio per diversi scenari.

Confronto sugli attributi della connessione tra la connessione in pool e la richiesta Nessuna integrazione/rimozione dell'integrazione Richiedi integrazione/rimozione aggiuntiva
Il catalogo (SQL_ATTR_CURRENT_CATALOG) è diverso 60 50
Alcuni attributi della connessione sono diversi, ma il catalogo è lo stesso 90 70
Tutti gli attributi di connessione corrispondono perfettamente 100 80

Diagramma di sequenza

Questo diagramma di sequenza illustra il meccanismo di pooling di base descritto in questo argomento. Mostra solo l'uso di SQLDriverConnect ma il caso di SQLConnect è simile.

Sequence Diagram

Diagramma di stato

Questo diagramma di stato mostra l'oggetto token delle informazioni di connessione, descritto in questo argomento. Il diagramma mostra solo SQLDriverConnect ma il caso di SQL Connect è simile. Poiché Gestione driver può avere bisogno di gestire gli errori in qualsiasi momento, può chiamare SQLFreeHandle per qualsiasi stato.

State Diagram

Vedi anche

Pool di connessioni compatibile con il driver
Riferimento dell'interfaccia del provider di servizi (SPI) ODBC