2009-05-22 21 views
5

¿Es una buena práctica tener un objeto SqlConnection compartido en una aplicación .NET para todas sus conexiones a la base de datos o debería tener uno diferente cada vez que acceda a la base de datos?Shared SqlConnection

Actualmente tengo uno compartido y parece que se está encontrando con problemas de repente. Parece que no puedo usar uno compartido cuando necesito usar el modo de autenticación de SQL en lugar del modo de autenticación de Windows. Lo intenté por primera vez usando la autenticación SQL y me dio este error cuando intenté usar la misma conexión por segunda vez:

Ya hay un lector de datos abierto asociado con este comando que debe cerrarse primero.

Respuesta

4

Deberías tener una realmente diferente. La reutilización de las conexiones se maneja con connection pooling. El segundo problema, como otros han dicho, probablemente se pueda resolver habilitando MARS.

0

Si está utilizando SQL Server 2000, this puede responder su pregunta.

Parece que la respuesta ganadora es "Esto se debe a un cambio en la configuración predeterminada para MAR. Solía ​​estar activada de manera predeterminada y la cambiamos a off por defecto después de RC1. Así que simplemente cambie su cadena de conexión a agréguelo de nuevo (agregue MultipleActiveResultSets = True a la cadena de conexión). "

1

Mucho de esto puede ser un dup from here; en resumen, mantenga las conexiones de corta duración y locales en la mayoría de las circunstancias. Re el lector de datos; quizás habilitar MARS?

1

Mientras que para un solo subproceso puede funcionar mejor usar un solo objeto SqlConnection, exige que el valioso recurso que es su servidor de base de datos cuelgue en una conexión, y así los recursos del servidor db, más de lo necesario.

Es mejor crear una instancia de SqlConnection por el menor tiempo posible. La agrupación de conexiones mitiga la mayor parte del gasto de configuración de la conexión y garantiza el uso más eficiente de los recursos de la base de datos.

3

Ese error no tiene absolutamente nada que ver con la autenticación. Está reutilizando una conexión del medio antes de cerrar su SqlDataReader devuelto desde un ExecuteReader(). Esto está prohibido. Debe verificar su código y eliminar su problema. Hay alternativas para usar MARS (multiple active record sets), pero desaprobaría eso.

El uso de conexiones múltiples en su aplicación probablemente será aún peor porque aparentemente usted no sabe qué conexión está en uso y cuándo, de modo que cuando use conexiones separadas se encontrará con problemas de consistencia de transacción.

+0

Si dice "no use MARS", ¿tiene algún motivo específico? Por curiosidad ... –

+0

http://blogs.msdn.com/sqlnativeclient/archive/2006/09/27/774290.aspx se analizan algunos de los aspectos negativos del uso de MARS – RichardOD

+2

El modelo de aislamiento de transacciones de MARS está incompleto, como en no completamente definido teóricamente. El resultado es que el servidor puede "confundirse", como admite el enlace publicado por Richard. Lo que normalmente significa esa "confusión" es que el número de posibles interacciones es demasiado grande y no todas las rutas de código en el servidor se prueban y validan. –

2

Su problema es que está intentando utilizar una conexión que actualmente está siendo utilizada por un SqlDataReader. No puedes hacer eso. Cuando usa un SqlDataReader, debe cerrarlo antes de reutilizar la conexión que se está consumiendo. Le sugiero que cree una conexión diferente cada vez que acceda a la base de datos (en cualquier momento, no solo con SqlDataReaders). Si tiene habilitado el agrupamiento, entonces el marco en sí (¿o es SqlServer?) Reutilizará las conexiones cuando sea posible.

Si necesita acceder a la base de datos secuencialmente, digamos que hace una selección, luego otra seleccione, y luego una actualización, puede reutilizar la conexión (es decir, la misma instancia SqlConnection), pero si necesita acceder el DB mientras lee de un SqlDataReader, entonces necesitará 2 conexiones diferentes.

Por supuesto, debe tener en cuenta los problemas de simultaneidad.Si usa transacciones, entonces algunos registros pueden estar bloqueados durante ciertas operaciones, y cuando usa el SqlDataReader en paralelo con otras consultas, debe establecer el nivel de aislamiento a un nivel que no se meta con el resto de las consultas.