2009-05-22 20 views
5

È buona norma disporre di un oggetto SqlConnection condiviso in un'applicazione .NET da utilizzare per tutte le connessioni del database o se ne deve essere separato ogni volta che si accede al database?Shared SqlConnection

Attualmente ne ho uno condiviso e sembra che si stia imbattendo in problemi all'improvviso. Sembra che non possa usare uno condiviso quando devo usare la modalità di autenticazione SQL invece della modalità di autenticazione di Windows. Ho appena provato per la prima volta utilizzando l'autenticazione SQL e mi ha dato questo errore quando ho provato a utilizzare la stessa connessione una seconda volta:

C'è già un DataReader aperto associato a questo comando che deve essere chiuso per primo.

risposta

4

Si dovrebbe avere uno separato davvero. Il riutilizzo delle connessioni viene gestito con connection pooling. Il secondo problema, come altri hanno affermato, può probabilmente essere risolto abilitando MARS.

0

Se si utilizza SQL Server 2000, this potrebbe rispondere alla domanda.

La risposta vincente sembra essere "Ciò è dovuto a una modifica dell'impostazione predefinita per MARs. Per impostazione predefinita era attivata per impostazione predefinita e l'abbiamo modificata su off per impostazione predefinita su RC1. aggiungilo di nuovo (aggiungi MultipleActiveResultSets = True alla stringa di connessione). "

1

Molto di questo può essere un dup from here; in breve, mantenere le connessioni di breve durata e locali nella maggior parte delle circostanze. Re il lettore di dati; forse abilitare MARS?

1

Mentre per un singolo thread può eseguire meglio l'utilizzo di un singolo oggetto SqlConnection, pone le richieste sulla preziosa risorsa che è il server del database agganciandosi a una connessione, e quindi alle risorse del server DB, più a lungo del necessario.

È meglio creare un'istanza di SqlConnection per un periodo di tempo il più breve possibile. Il pool di connessioni riduce la maggior parte delle spese di configurazione della connessione e garantisce l'utilizzo più efficiente delle risorse del database.

3

Questo errore non ha assolutamente nulla a che fare con l'autenticazione. Stai riutilizzando una connessione dalla metà prima di aver chiuso SqlDataReader restituito da un ExecuteReader(). Questo è proibito Devi controllare il tuo codice ed eliminare il tuo problema. Ci sono alternative per usare MARS (multiple active record sets) ma lo sconsiglio vivamente.

L'utilizzo di più connessioni nella tua applicazione sarà probabilmente ancora peggiore perché apparentemente non sai quale connessione è in uso e quando, quando utilizzerai connessioni separate, ti imbatterai in problemi di coerenza delle transazioni.

+0

Se stai dicendo "non usare MARS", hai delle ragioni specifiche? Per curiosità ... –

+0

http://blogs.msdn.com/sqlnativeclient/archive/2006/09/27/774290.aspx discute alcuni dei negativi all'utilizzo di MARS – RichardOD

+2

Il modello di isolamento della transazione di MARS è incompleto, come in non completamente definito teoricamente. Il risultato è che il server potrebbe diventare "confuso", come ammette il link pubblicato da Richard. Che cosa "confusione" di solito significa è che il numero di interazioni possibili è troppo grande e non tutti i percorsi di codice nel server vengono testati e convalidati. –

2

Il problema è che si sta tentando di utilizzare una connessione attualmente utilizzata da SqlDataReader. Non puoi farlo. Quando si utilizza SqlDataReader, è necessario chiuderlo prima di riutilizzare la connessione che si sta consumando. Ti suggerisco di creare una connessione diversa ogni volta che accedi al DB (in qualsiasi momento, non solo con SqlDataReaders). Se il pool è abilitato, il framework stesso (o è SqlServer?) Riutilizzerà le connessioni quando possibile.

Se è necessario accedere al DB in modo sequenziale, diciamo che si effettua una selezione, quindi un'altra selezione, e quindi un aggiornamento, è possibile riutilizzare la connessione (intendo la stessa istanza SqlConnection), ma se è necessario accedere il DB durante la lettura da un SqlDataReader, quindi avrete bisogno di 2 connessioni diverse.

Naturalmente è necessario avere in mente problemi di concorrenza.Se si utilizzano le transazioni, alcuni record potrebbero essere bloccati durante determinate operazioni e, quando si utilizza SqlDataReader in parallelo con altre query, è necessario impostare il livello di isolamento su un livello che non interferisca con il resto delle query.