Proseguiamo l'analisi sull'approccio migliore per la scrittura di un DAL che risponda a richieste di più client in contemporanea (eventualmente smistate su più database):
Consideriamo per ora l'ipotesi semplificativa di DAL che debba connettersi ad un solo db, con un unica stringa di connessione. Scartiamo l'idea di aprire una connessione unica all'avvio dell'applicazione, perché stiamo parlando di architetture distribuite, in cui le richieste di servizio non sono contigue: non vogliamo occupare una risorsa del db se non ne facciamo uso: apriremo una connessione solo quando un client ci chiederà un servizio.
Si osservi che, per il nostro DAL, il servizio richiesto dal client coincide con una funzione pubblica.
Dobbiamo aprire la connessione all'avvio della funzione pubblica e chiuderla alla fine, prima di restituire al client la risposta.
Come viene effettuata l'apertura della connessione? Tipicamente avremo una libreria di accesso allo specifico database, a cui chiederemo la connessione. Qui occorre operare una scelta: la libreria ci fornisce una nuova connessione creata apposta, oppure un puntatore ad un'unica connessione?
Nella prima figura immaginiamo che tre client invochino quasi contemporaneamente tre funzioni pubbliche, e che il DAL, per ogni funzione, richieda al database la connessione.
Se l'architettura applicativa prevede che il database restituisca tre puntatori all'unica connessione, alla fine della funzione 3 la connessione verrà chiusa, le funzioni 1 e 2 che sono ancora in esecuzione corrono il rischio di effettuare operazioni su una connessione chiusa, generando errori.
Questo tipo di architettura può funzionare se e solo se esiste un solo client che invoca i metodi pubblici del DAL, e se li invoca in ordine strettamente seriale; qualsiasi parallelismo porterà certamente a condizioni d'errore. Quindi per un ambiente distribuito occorre operare una scelta diversa.
Nella seconda figura il database crea una nuova connessione per ognuna delle tre funzioni: questo ci permette di rispondere a più client in parallelo.
Per quanto riguarda le performance, questo ultimo approccio naturalmente pone un dubbio: la continua creazione, apertura e chiusura di connessioni può essere un punto di attenzione a livello di prestazioni.
In ambiente .NET, le best practices ADO.NET suggeriscono di fare uso del connection pool, delegando al framework l'effettiva chiusura ed apertura delle connessioni: si veda
http://msdn.microsoft.com/en-us/library/8xx3tyca(vs.71).aspx.