none
No se cierran las conexiones con la BBDD. RRS feed

  • Pregunta

  • Buenos dias,

    tengo un problema al cerrar la conexion con la BBDD, cuando un .Close() de la conexion, esta no se cierra y se queda en sleeping, y lo peor de eso es que hay bloqueos que dependen de estas conexiones en sleeping.

    He lanzado esta consulta en el foro de SQL Server http://social.msdn.microsoft.com/Forums/es-ES/sqlserveres/thread/77f2e2ea-d6c6-45d2-a9fe-9964cc1c3676

    Tambien he estado haciendo pruebas para conectarme con una base de datos.

    static void Main(string[] args)
            {
                Console.WriteLine("11111111");
                proc1();
                Console.WriteLine("22222222");
            }
    
            public static void proc1()
            {
                lock (a)
                {
                    SqlConnection conn = new SqlConnection(a);
                    conn.Open();
                    Console.Write("aaaaaaaaaaaaaaa");
                    conn.Close();
                    Console.Write("bbbbbbbbbbbbbbb");
                }
            }

    he detectado que la conexion se crea cuando se hace  .Open() (esto es normal), pero cuando hago .Close() no se cierra la conexiones todo esto lo estoy monitorizando con el procedimiento almacendo sp_who, y el tema de los bloqueos con sp_who y sp_lock.

    por añadir mas informacion, hasta que la aplicacion no termina la conexion no se cierra algo que me parece extraño...

    Sabeis por que pueden venir todos estos problemas???

    PD: La imagen de la otra consulta no corresponde con este codigo, esto solo son unas pruebas que he hecho.

    Un saludo y gracias,

    miércoles, 18 de abril de 2012 9:33

Todas las respuestas

  • Desconozco el manejo que hace SqlServer con las conexiones. Recuerdo haber leido algo que decía que cuando tu cerrabas una conexión el .NET o el SqlServer (no recuerdo quien) no la hacía desaparecer por si podía reciclarla en cierto tiempo, aunque ese proceso de "dejar pendiente" no debería bloquear recursos.

    Lo que si te recomiendo es que cambies la forma de usar la conexión. Te recomiendo el uso de using de la siguiente manera

    using (SqlConnection conn = new SqlConnection(a))
    {
      conn.Open();
      // Tus operaciones con la base de datos
    
      // conn.Close() no hace falta porque se hace junto a conn.Dispose() cuando se sale del bloque using
    }


    Atentamente, Sergio.

    Blog
    Twitter


    • Editado sergiomf miércoles, 18 de abril de 2012 10:27
    miércoles, 18 de abril de 2012 10:00
  • He probado a hacerlo tal y como indicas, pero el resultado es el mismo, cuando sale del metodo proc1() la conexion sigue activa.. :S

    Googleando un poco he visto que el problema tambien puede ser del pool de conexiones, pero no tengo nada de estoconfigurado en la cadena de conexion asi que supongo que estara como viene por defecto.

    Se os ocurre alguna cosilla mas ??

    un saludo,

    miércoles, 18 de abril de 2012 10:10
  • una tontería, que lo mismo no tiene nada que ver (lo desconozco xD), pero por probar...has probado hacer conn.Dispose() antes de cerrarla??
    miércoles, 18 de abril de 2012 10:15
  • una tontería, que lo mismo no tiene nada que ver (lo desconozco xD), pero por probar...has probado hacer conn.Dispose() antes de cerrarla??
    Hola, el using ya se encarga de hacer un .Close() y .Dispose() de la conexión...

    Atentamente, Sergio.

    Blog
    Twitter

    miércoles, 18 de abril de 2012 10:17
  • Si, he probado de las 2 opciones, cuando no tenia el using() he puesto el .Close() y el .Dispose() y no cerraba la conexion, sin embargo, ahora tengo este codigo y si cierra la conexion, me parece un poco curioso... 
    public static void proc1()
            {
                using (SqlConnection conn = new SqlConnection(a))
                {
                    conn.Open();
                    Console.Write("aaaaaaaaaaaaaaa");
                    conn.Close();
                    Console.Write("bbbbbbbbbbbbbbb");
                    SqlConnection.ClearPool(conn);
                    Console.Write("ccccccccccccccc");
                }
            }

    miércoles, 18 de abril de 2012 10:22
  • Vale, pues viendo esto tiene sentido. El .NET mantiene un pool de conexiones, y cuando tu la cierras (.Close() o .Dispose()) el propio .NET la mantiene por si se requiere otra conexión poder reutilizarla y no tener que volver a "crearla".

    Te dejo esto que me ha parecido bastante interesante y te explica un poco más todo esto en detalle.

    http://blogs.msdn.com/b/warnov/archive/2009/08/16/problemas-con-el-connection-pool-de-ado-net.aspx


    Atentamente, Sergio.

    Blog
    Twitter

    miércoles, 18 de abril de 2012 10:29
  • hola

    un comentario adicional, coincido con Sergio de usar el using para definir la conexion a la db, el cual no requeire que definas el Close()

    pero ojo porque si lo defines de esta forma puede que sigas detectando la conxion por un instante, ya que es ado.net quien administra un pool de conexiones

    esta funcionalidad esta muy bien por parte de ado.net ya que aunque se realice el close este no es inmediato, sino que lo deja latente un rato por si se abre nueva conexion al misma db

    lo comento por si es esto lo que detectas en tus pruebas

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    miércoles, 18 de abril de 2012 12:01
  • Al Poner el Pooling = false en la cadena de conexión da este error {"El administrador de transacción ha deshabilitado su soporte para transacciones de red o remotas. (Excepción de HRESULT: 0x8004D024)"},

    Es curioso ya que la primera vez que abro la conexión funciona bien, incluso si lanzo el sp_who en el SSMS la conexión se cierra, pero cuando quiero abrir de nuevo la conexión es cuando lanza el error.

    Sabéis que puede ser??

    Un saludo,
    miércoles, 18 de abril de 2012 13:26
  • yo no deshabilitaria el pooling es clave para la performance de la aplicacion


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    miércoles, 18 de abril de 2012 13:31
  • Entonces como puedo evitar los bloqueos por conexiones en sleeping??
    miércoles, 18 de abril de 2012 13:40
  • Es que realmente eso es lo que me sorprende. Yo nunca he tocado el pool de conexiones de .NET y las conexiones que se quedan en sleeping nunca me han bloqueado ningún recurso.

    Atentamente, Sergio.

    Blog
    Twitter

    miércoles, 18 de abril de 2012 13:42
  • Me extraña mucho que una vez hecho el Close, Dispose o terminar el using se queden bloqueos. Por lo que yo sé, debería quedarse la conexión en sleeping, pero los bloqueos deberían haberse liberado al cerrarse la transacción.

    Has probado esto?

    public static void proc1()
            {
                using (SqlConnection conn = new SqlConnection(a))
                {
                    conn.Open();
    
                    // update de la BD
                }
    
                // Aquí debería estar la conn como sleeping pero NO debería haber ningún bloqueo
            }


    Xavi Paper

    viernes, 20 de abril de 2012 0:27