Quanto è grave non disporre di Dispose () SqlConnections?

13

Personalmente, scomodo negli alveari se non inserisco oggetti ADO che implementano IDisposable nell'uso delle istruzioni. Ma al mio attuale contratto, ho scoperto che il loro codice di "fornitore di accesso ai dati" della struttura aziendale interna non 1) implementa IDisposable e 2) chiama Dispose () su qualsiasi cosa utilizzi, in qualsiasi momento e in qualsiasi momento. Gli utenti hanno lamentato una grande quantità di problemi di prestazioni nelle applicazioni Winforms che utilizzano pesantemente questo framework per l'accesso ai dati, e sebbene ci siano molti altri problemi nel codice che potrebbero colpire le prestazioni, questo mi urla contro ed è più frutta a frutto basso rispetto agli altri.

Quindi, oltre a dire qualcosa come "Dispose è lì per un motivo, usalo", cosa posso dire a queste persone per convincerle che questo è davvero, davvero cattivo?

    
posta AJ Johnson 09.11.2010 - 20:51
fonte

5 risposte

6

Direi che la cosa migliore che puoi fare è indicarle su Pattern and Practices di Microsoft per quanto riguarda Dispose() qui . Lascia che vedano tutte le conseguenze di non utilizzare questo strumento proprio di fronte a loro.

    
risposta data 09.11.2010 - 21:04
fonte
9

Se non chiami il metodo Dispose su una connessione SQL, quando hai finito di usarlo, quella connessione NON viene restituita al pool di connessioni.

Se si verificano problemi di prestazioni, suppongo che le connessioni massime siano aperte sul database. Un DBA potrebbe facilmente confermarlo.

Microsoft Best Practice richiede all'utente di inserire il codice di connessione all'interno di un'istruzione Using, assicurandosi che la connessione sia eliminata e che la connessione venga restituita al pool.

    
risposta data 09.11.2010 - 21:03
fonte
8

Il pool di connessione al database è di dimensioni limitate e, se si riempie, le nuove connessioni attenderanno il rilascio delle vecchie connessioni. Se non li disponi non appena hai finito con loro, saranno eventualmente rilasciati quando il finalizzatore verrà eseguito, ma è una quantità indeterminata di tempo nel futuro ... Quindi a meglio, vedrai lunghi ritardi quando apri nuove connessioni.

Nel peggiore dei casi, potrebbero aver disabilitato il pool di connessioni. Forse hanno scoperto che dopo un po 'la loro app stava restituendo errori di "timeout in attesa di connessione" e disabilitando il pool di connessioni "risolto" quel problema. Tuttavia, questo è molto peggio perché significa che stai creando una nuova nuova connessione ogni volta, il che è sorprendentemente dispendioso in termini di risorse. Se hai centinaia di connessioni al database aperte, non c'è da meravigliarsi se vedi problemi di prestazioni.

Il modo corretto per risolvere tutti questi problemi è quello di eliminare la connessione non appena hai finito con esso. L'idea migliore è di mantenere la connessione aperta esattamente per il tempo necessario e non più.

    
risposta data 09.11.2010 - 23:21
fonte
3

In qualsiasi applicazione seria direi che è piuttosto brutto. Non solo lascerà questi oggetti galleggiare intorno alle prestazioni di uccisione, ma è anche semplicemente poco professionale. La buona notizia è che Microsoft implementa Finalize nella gerarchia degli oggetti.

~Object()
{
    this.Dispose(false);    
}

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    // ...
}

Prendi System.Data.SqlClient.SqlConnection ad esempio:

System.ComponentModel.Component <-- Implements the Finalize dispose pattern.
    |
System.Data.Common.DbConnection
    |
System.Data.SqlClient.SqlConnection

Gli oggetti verranno infine eliminati, ma la natura non deterministica arreca scompiglio alle prestazioni.

    
risposta data 09.11.2010 - 21:06
fonte
0

Bene, per esempio, non stai terminando la connessione. Quindi o deve essere a) Lasciar cadere automaticamente o b) Ottenere il ciclo e aggiornato anche se il client non ha alcuno scopo.

Assumerei b) a causa del colpo di performance che stai descrivendo. Tuttavia, questo non è probabilmente l'unico motivo.

DEVI chiudere le connessioni, preferibilmente dal lato client, ma devi anche implementare un fail safe sul lato server. Altrimenti hai solo un mucchio di crap in più che il tuo server di database deve elaborare fino a quando non viene rilasciato a dio-sa-quando.

    
risposta data 26.07.2011 - 04:39
fonte

Leggi altre domande sui tag