2010-12-14 15 views
82

Tengo mi lógica de negocio implementada en clases estáticas simples con métodos estáticos. Cada uno de estos métodos se abre/cierra la conexión de SQL cuando se le llama:"abrir/cerrar" SqlConnection o mantener abierto?

public static void AddSomething(string something) 
{ 
    using (SqlConnection connection = new SqlConnection("...")) 
    { 
     connection.Open(); 

     // ... 

     connection.Close(); 
    } 
} 

pero creo evitando la apertura y el cierre de una conexión ahorra rendimiento. Hice algunas pruebas muuuucho tiempo atrás con OleDbConnection clase (no estoy seguro sobre el SqlConnection), y que sin duda ayudó a trabajar así (por lo que yo recuerdo):

//pass the connection object into the method 
public static void AddSomething(string something, SqlConnection connection) 
{ 
    bool openConn = (connection.State == ConnectionState.Open); 
    if (!openConn) 
    { 
     connection.Open(); 
    } 

    // .... 

    if (openConn) 
    { 
     connection.Close(); 
    } 
} 

Así que la pregunta es - debería elegir el método (a) o el método (b)? Leí en otra pregunta stackoverflow que la conexión agrupa el rendimiento guardado para mí, no tengo que molestar en absoluto ...

PS. Es una aplicación ASP.NET: las conexiones existen solo durante una solicitud web. No es una aplicación o servicio win.

+1

Solo un consejo: utilice el evento 'DbConnection.StateChange' para controlar los cambios en el cambio de estado de la conexión (y se pueden almacenar localmente) en lugar de verificar directamente la propiedad' DbConnection.State'. Le ahorrará costos de rendimiento. – decyclone

+1

Un detalle que falta es cómo este método es parte de una solicitud de página. ¿Es el único método llamado o es, como asumí en mi respuesta, uno de los muchos métodos que se llama en un pedido de página, afecta a cuál respuesta es correcta;) –

+0

David - MUCHOS métodos como este se llaman :) – Alex

Respuesta

59

Se adhiere a la opción a.

El grupo de conexiones es tu amigo.

+23

en mi humilde opinión - ni siquiera debería cerrar. la disposición lo hará. –

+2

@RoyiNamir Me gusta un poco la llamada para cerrar la conexión. Especialmente para principiantes y recién llegados a una base de código. Es más explícito y legible. – edhedges

+10

@edhedges Utilizar tanto "usar" como Cerrar() solo causará confusión para los recién llegados. No van a entender el propósito de utilizar "usar". No utilice "Cerrar" en su lugar, enséñeles el propósito de "usar". Para que puedan aprender a mejorar y aplicar lo que aprenden a otras partes del código. –

25

Siempre cierre las conexiones tan pronto como haya terminado con ellas, para que la conexión de la base de datos subyacente pueda volver al grupo y esté disponible para otras personas que llaman. La agrupación de conexiones está bastante optimizada, por lo que no hay una penalización notable por hacerlo. El consejo es básicamente el mismo que para las transacciones: manténgalas cortas y cerradas cuando haya terminado.

Se vuelve más complicado si se encuentra con problemas MSDTC al usar una sola transacción alrededor del código que usa conexiones múltiples, en cuyo caso tiene que compartir el objeto de conexión y solo cerrarlo una vez que la transacción finaliza .

Sin embargo, usted está haciendo las cosas a mano aquí, por lo que es posible que desee investigar las herramientas que gestionan las conexiones para usted, como DataSets, Linq a SQL, Entity Framework o NHibernate.

+0

Normalmente, no debería abrir y cerrar una conexión dentro de cada llamada a método, solo una vez por cada solicitud de página. Eso es lo que aprendí al menos;) La apertura y el cierre cuestan tiempo. –

+7

@David Martensson: las conexiones no se abren y cierran cuando se llama a SqlConnection.Open. ASP.NET recicla las conexiones activas del grupo cuando la cadena de conexión coincide con una cadena de conexión utilizada anteriormente. La sobrecarga involucrada en esto es irrelevante, y además, tratar de "hacerlo usted mismo" significa que debe asumir todas las tareas administrativas de garantizar que la conexión aún esté activa para cada uso posterior, lo que agrega complejidad y gastos generales. Con la agrupación de conexiones, la mejor práctica es abrirlo y cerrarlo para cada uso. –

+2

Con todo mi respeto, la respuesta "Siempre cerrar las conexiones" no encaja muy bien en la pregunta ... Los cierro. La pregunta es - cuando. – Alex

66

Utilice el método (a), cada vez. Cuando comiences a escalar tu aplicación, la lógica que trata con el estado se convertirá en un verdadero dolor si no lo haces.

La agrupación de conexiones hace lo que dice en la lata. Solo piense en lo que sucede cuando la aplicación escala, y qué tan difícil sería administrar manualmente el estado de apertura/cierre de la conexión. El grupo de conexiones hace un buen trabajo al manejar esto automáticamente. Si le preocupa el rendimiento, piense en algún tipo de mecanismo de memoria caché para que nada se bloquee.

+3

Te hubiera votado +50 si pudiera :-) –

6

Existen distinciones entre las conexiones físicas y lógicas. DbConnection es un tipo de conexión lógica y utiliza una conexión física subyacente a Oracle. Cerrar/abrir DbConnection no afecta su rendimiento, pero hace que su código esté limpio y estable; las fugas de conexión son imposibles en este caso.

También debe recordar los casos en que existen limitaciones para las conexiones en paralelo en el servidor de base de datos, teniendo en cuenta que es necesario hacer sus conexiones muy breves.

El grupo de conexiones lo libera de la comprobación del estado de la conexión: simplemente ábralo, úselo y ciérrelo inmediatamente.

+0

Sí, la conexión no es la conexión, es decir, DbConnection no es la conexión física. DbConnection es una clase .NET que proporciona métodos y propiedades para manipular la conexión física subyacente. –

10

Descargo de responsabilidad: Sé que esto es viejo, pero encontré una manera fácil de demostrar este hecho, por lo que estoy poniendo en mi valor de dos centavos.

Si usted está teniendo problemas para creer que la puesta en común es realmente va a ser más rápido, a continuación, dar a este un intento:

Añadir la siguiente parte:

using System.Diagnostics; 
public static class TestExtensions 
{ 
    public static void TimedOpen(this SqlConnection conn) 
    { 
     Stopwatch sw = Stopwatch.StartNew(); 
     conn.Open(); 
     Console.WriteLine(sw.Elapsed); 
    } 
} 

Ahora reemplace todas las llamadas a Open() con TimedOpen() y ejecuta su programa. Ahora, para cada cadena de conexión distinta que tenga, la ventana de la consola (salida) tendrá una única ejecución larga abierta, y se abrirá rápidamente un grupo de muy.

Si desea etiquetarlos puede agregar new StackTrace(true).GetFrame(1) + a la llamada al WriteLine.

Cuestiones relacionadas