Connection Pools

11/04/2007 - 15:22 por Diego Jancic | Informe spam
Hola Gente!,
Estoy con un bug bastante importante y no logro encontrar el problema,
espero que me puedan tirar alguna idea..
Estoy haciendo un componente de acceso a datos que funciona sobre el
Data Access App Block y estoy recibiendo el error:

System.InvalidOperationException: Timeout expired. The timeout period
elapsed prior to obtaining a connection from the pool. This may have
occurred because all pooled connections were in use and max pool size
was reached.

Cuando creo el componente, debido a que necesito usar transacciones
hago:

DaabDB = new SqlDatabase(connString);
Connection = DaabDB.CreateConnection();
Connection.Open();

Y cuando llamo al Dispose (que ahora lo estoy llamando manualmente),
hago:

Connection.Close();
Connection.Dispose();
Connection = null;
DaabDB = null;

Y asi y todo no logro hacer que el error deje de pasar...

La unica forma que deje de pasar el llamar al GC.Collect() en el
Dispose del componente, pero esto no es muy adecuado por temas de
performance..


Gracias,
Diego
 

Leer las respuestas

#1 Alberto Poblacion
11/04/2007 - 16:03 | Informe spam
"Diego Jancic" wrote in message
news:
System.InvalidOperationException: Timeout expired. The timeout period
elapsed prior to obtaining a connection from the pool.
[...]
DaabDB = new SqlDatabase(connString);
Connection = DaabDB.CreateConnection();
Connection.Open();

Y cuando llamo al Dispose (que ahora lo estoy llamando manualmente),
hago:

Connection.Close();
Connection.Dispose();



Invariablemente ese error ocurre cuando en algún sitio se te escapa
alguna conexión sin cerrar. La siguiente que se abre se toma del pool, con
lo que el pool va creciendo, y cuando llega al tamaño máximo, se queda 20
segundos esperando a que se libere alguna, y como nunca se liberan, da un
error de timeout.

Entre el Open() y el Close(), se te ha debido escapar en tu código algún
caso en que se abandona la ejecución (por ejemplo, con un return o con un
throw) sin haber hecho el Close. Para evitar que esto suceda, el remedio es
meter todo el bloque en un try...finally, y dentro del finally hacer el
Close. De esta forma siempre se ejecuta, incluso aunque hagas un return
entre medias.

La unica forma que deje de pasar el llamar al GC.Collect()



Justo, el Collect fuerza la ejecución del recogedor de basura, éste
llama a los Finalizers de todos los objetos no finalizados, y el Finalize de
la conexión llama al Dispose, por eso te deja de dar el error.

Preguntas similares