Connection Pooling
Certo, non è una novità del .NET Framework che il connection pooling sia una funzionalità molto interessante nelle applicazioni che accedono a un database server, ma in questo caso il vantaggio è veramente interessante. Una prova di tutto ciò è che per quanto riguarda il SQL Server .NET Data Provider, il connection pooling è abilitato di default e l’utilizzo è quasi completamente trasparente allo sviluppatore. I vantaggi sono sostanzialmente di due tipi:
- tempi ridotti al momento di stabilire una connessione verso la fonte dati
- utilizzo delle risorse del server ottimizzato rispetto al numero di utenti serviti
I pool di connessioni vengono creati a livello di processo client, e rimangono in vita fino al termine del processo stesso. Alla apertura di una connessione è possibile configurare alcune caratteristiche del comportamento della connessione stessa nei confronti del connection pooling. Gli attributi Min Pool Size e Max Pool Size infatti consentono di stabilire il numero minimo e massimo di connessioni presenti all’interno del pool dove la connessione adrà a risiedere.
Le connessioni all’interno di un pool devono avere caratteristiche “compatibili” come ad esempio il contesto di sicurezza utilizzato e il nome del database target. Attenzione perchè il meccanismo di gestione del pooling è molto sensibile al contenuto della ConnectionString in termini di sintassi utilizzata, e basta uno spazio in più o in meno in un punto differente del codice perchè venga creato un nuovo pool di connessioni invece che venga utilizzato uno esistente. Quando il numero di connessioni in un pool raggiunge il valore massimo possibile, le successive richieste di apertura vengono accodate per un tempo configurabile attraverso il parametro Connect Timeout.
Nella versione RTM del Framework il pooling è abilitato anche all’interno dell’ambiente di sviluppo, mentre nelle beta precedenti non funzionava.
Se la connessione è associata al contesto di una transazione, viene creato un pool specifico per tutte le connessioni associate a quella transazione, mentre per tutte le connessione non associate ad un contesto, viene creato un pool comune. Ovviamente per poter utilizzare correttamente e con profitto il connection pooling occorre che il processo client utilizzi coerentemente la connessione cioè la apra solo al momento in cui ne ha bisogno e la chiuda immediatamente dopo, utilizzando il metodo Close() oppure Dispose() o il pattern ‘using’.
La rimozione di una connessione dal pool viene eseguita dal connection pooler quando il Connection Lifetime è trascorso, oppure quando questa viene marcata come invalida perchè il server non è più disponibile. Questa eliminazione non è immediata, ma dilazionata nel tempo.
Proprio per l’importanza che il pooling ha per le performances delle applicazioni, sono stati creati una serie di counter che rendono possibile il monitoraggio di questa funzionalità e la messa a punto delle applicazioni.
|
Counter |
Descrizione |
|
SqlClient: Current # of pooled and non pooled connections |
Numero delle connessioni, in pool oppure no, aperte da un determinato processo |
|
SqlClient: Current # pooled connections |
Numero delle connessioni presenti in tutti i pool associati con un determinato processo |
|
SqlClient: Current # connection pools |
Numero dei pool associati ad un determinato processo |
|
SqlClient: Peak # pooled connections |
Il massimo numero di connessioni presenti in tutti i pool dalla partenza di un processo |
|
SqlClient: Total # failed connects |
Il numero di tentativi di connessione che sono falliti per qualsiasi motivo per quel processo |
Un altro modo per monitorare il funzionamento del pooling è quello di utilizzare il SQL Server Profiler, presente all’interno dei tools installati dalla parte client di SQL Server, che consente di tracciare qualsiasi attività che avviene tra i vari processi client ed un server. In particolare gli eventi da catturare sono quelli di Audit Login e Audit Logout che si trovano raggruppati sotto la categoria Security Audit.
Un particolare da non dimenticare è che i pool rimangono in vita per tutta la durata del processo client e quindi, la creazione indiscriminata di molti pool avrà un minimo di overhead sulle performance dell’applicazione.
Continua....
