2012-03-21 13 views
7

no estoy usando LINQ a SQL o trozos de Entity Framework en una aplicación web, y actualmente han estado usando algo como esto (esto es para un proyecto de clase):¿Cómo se debe mantener una conexión de base de datos en una aplicación ASP.NET MVC?

using System.Data; 
using System.Data.SqlClient; 

namespace StackOverflowClone.Models 
{ 
    public class Database 
    { 
     public static SqlConnection ActiveConnection { get; private set; } 

     static Database() 
     { 
      ActiveConnection = new SqlConnection(
       "Data Source=********.database.windows.net;" + 
       "Initial Catalog=EECS341;Uid=*****;Pwd=*******;" + 
       "MultipleActiveResultSets=True;"); 
      ActiveConnection.Open(); 
     } 
    } 
} 

Sin embargo, esto parece ser la causa problemas de enhebrado porque el inicializador estático se ejecuta una vez por proceso de servidor, en lugar de una vez por solicitud.

¿El marco proporciona un sistema incorporado en el método de manipulación de este o debo tener una función que tose conexiones de base new'd arriba cada vez?

+0

@TomasVoracek: El problema es que puede haber más de un usuario atendido a la vez, y la conexión ocasionalmente se confunde y falla una consulta porque un hilo diferente aún está leyendo los resultados de una consulta previa. –

Respuesta

12

o debería simplemente tener una función que espere nuevas conexiones de base de datos cada vez?

Sí, hacer esto. Deje que ADO.NET connection pooling maneje los detalles por usted. Su objetivo debe ser mantener la conexión abierta durante el menor tiempo posible.

La agrupación de conexiones reduce el número de veces que deben abrirse las nuevas conexiones . El pooler mantiene la propiedad de la conexión física . Gestiona las conexiones manteniendo vivo un conjunto de conexiones activas para cada configuración de conexión determinada. Cada vez que un usuario llama a Abrir en una conexión, el agrupador busca una conexión disponible en el grupo. Si hay una conexión agrupada disponible, la devuelve a la persona que llama en lugar de abrir una nueva conexión. Cuando la aplicación llama a Cerrar en la conexión, la agrupación lo devuelve a conjunto agrupado de conexiones activas en lugar de cerrarlo. Una vez que la conexión se devuelve al grupo, está lista para ser reutilizada en la próxima llamada abierta .

Por lo tanto, cree un método GetConnection() estático que devuelva una nueva conexión abierta. Úselo en una declaración using para que pueda cerrarse y devolverse al grupo de conexiones lo antes posible.

using(var cn = Database.GetConnection()) 
{ 
    //query your data here, Dapper example below 
    cn.Execute("update MyTable set MyField = @newValue", new {newValue}); 
} 
+0

Pooling de conexión? ¿Que es eso? –

+0

@BillyONeal - [Grupo de conexiones] (http://en.wikipedia.org/wiki/Connection_pool). – Oded

+2

@BillyONeal: Parece que es un grupo de conexiones ... Tal vez Google sabe más. –

4

crear siempre nuevas conexiones y destruirlos con using. En realidad, no se crean desde cero, se obtienen de un connection pool. No hay penalización de rendimiento. En realidad, esa es la mejor y más correcta forma de hacerlo.

Véase mi respuesta sobre using: https://stackoverflow.com/a/9811911/290343

+0

: suspiro: otro nivel más de uso para ejecutar una consulta simple. Ya tenemos uno para SqlCommand, uno para la transacción, uno para el lector y otro para los registros de lectura de bucle. Supongo que si lo que tenemos que hacer es lo que tenemos que hacer, pero parece doloroso estar haciendo esto cada vez. –

+0

@BillyONeal depende de qué API use para acceder a la base de datos. Te recomiendo que revises [Dapper] (http://www.google.ca/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCsQFjAA&url=http%3A%2F%2Fcode.google.com%2Fp % 2Fdapper-dot-net% 2F & ei = PjRqT76cMqLf0QGBwozxAQ & usg = AFQjCNHDo-0KnatIhtMQ4pvQ0QLhup59Wg). Extremadamente simple. – RedFilter

+0

@BillyONeal: Puedes apilar usando declaraciones ... Si tengo varias, evito poner un corsé en la siguiente línea. Lo hace mucho más limpio. –

1

¿Establece el marco construido en un método de manejar esto o debería sólo tienen una función que tose conexiones de base new'd arriba cada vez?

Ambos, en realidad.

El servidor web tiene varios hilos, por lo que cada hilo necesita su propia conexión a la base de datos. Solo crea uno cuando sea necesario.

Las conexiones reales a la base de datos se agrupan. Cuando desecha un objeto de conexión, la conexión real no se cierra, sino que se devuelve al grupo.Si crea un nuevo objeto de conexión con la misma cadena de conexión, solo reutilizará una conexión del grupo.

Cuestiones relacionadas