Pool de conexiones en PHP

Rodrigo Fuentealba darkprox en gmail.com
Jue Feb 9 19:02:27 CLST 2006


Hola:
>
>     Estoy implementando un sistema de registro de alumnos en PHP5 /
>     Postgres con tres capas, no estoy utilizando ningun framework o
>     uno de esos otros chiches (quisiera toparme con estos problemillas
>     primero). Mi consulta radica en la forma en que hago mis
>     conexiones de base datos, si bien es cierto hay q dejar todo el
>     peso de las conexiones a la capa de persistencia de datos, esto
>     hace q abra y cierre las conexiones a cada rato.
>     Por ejemplo en el caso de cargar un objeto alumno haria:
>     Código PHP:
>     | |
>     | function buscarAlumno( $codigo){
>         $con = new Conexion ();
>         $con->conectarse();
>
>          // hago mi consulta
>         $con->query( $sql)
>
>         $alumno = new Alumno ();    
>         $alumno->colegio =  Colegio::buscarColegio($data[ "cod_colegio"]);
>         //este metodo internamente tambien abre y cierra una conexion;
>          $alumno->ciudad = Colegio:: buscarCiudad($data["cod_ciudad" ]);
>         //esta tambien
>         //... y cuantas tuviera
>
>         $con ->cerrar_conexion();
>         // cerramos la conexion de al inicio
>          return $alumno;
>     }  |
>
> KATE O KWRITE :P
>
¿A qué viene eso?
>
>     Esto abriria y cerraria muchas conexiones por lo q reventaria el
>     limite de estas.
>
>
> depende si estas tu motor de base de datos soporta conexiones 
> persistentes y no cierras las conexiones no deberia reventar
PostgreSQL sí soporta conexiones persistentes. Simplemente tienes que 
modificar algunas cosas. Creo que tu pregunta es más sencilla de 
resolver que lo que se ve en el correo.

voy a hacer un pequeño pseudocódigo (ando con jaquecas hoy) que te guíe.

<?php

    function buscar_colegio()
    {
        if(!conexion->abierta)
        {
            abrir_conexion();
        }
        codigoparabuscar->colegio;
    }

    function buscaralumno()
    {
        abrir_conexion();
        alumno = new alumno();
        buscar_colegio();
        buscar_ciudad();
        return alumno();
        cerrar_conexion();
    }

?>

Aunque PHP al finalizar el script cierra las conexiones y libera la 
basura, yo personalmente recomiendo cerrar las conexiones puesto que el 
garbage collector igual ocupa algo más de memoria, pues debe "adivinar" 
qué cosas están abiertas. Aqui solamente abres una conexion aparte si no 
hay ninguna conexión abierta, lo cual quiere decir que te ahorras una 
conexión a la base de datos por cada vez que con el esquema anterior 
tienes problemas. ;)

>     Otro caso es este:
>     Código PHP:
>     | |
>     |
>     function buscarAlumno( $con ,$codigo){
>         $alumno = new  Alumno();
>         // hago mi consulta
>         $con ->query($sql)
>         $alumno ->colegio = Colegio:: buscarColegio($con,$data
>     ["cod_colegio"]);
>         //usa la conexion ya disponible;
>          $alumno->ciudad = Colegio:: buscarCiudad($con,$data
>     ["cod_ciudad"]);
>         //este tambien
>         //... y cuantas tuviera
>
>          return $alumno;
>     } 
>     |
>
>     Aqui mando mi conexion abierta desde fuera, pero esto haria que el
>     que abra mi conexion sea mi capa de logica de negocio, pero
>     supuestamente esta no debería ser su funcion, ademas imaginemos q
>     el metodo de la capa de logica sea un poco extensa, la conexion
>     estaria abierta mucho tiempo, y eso tambien acarrearia problemas.
>     La pregunta del millon es esta...
>     ¿Cual de las dos formas es la mas optima a utilizar?
>
>
> mmm no me convence ninguna
A mí tampoco me convence ninguna. Veo que estás tratando las tres capas 
como algo totalmente separado, cuando en verdad es algo común que en 
algunas partes se junten. El concepto de N-Tier, según como yo lo 
entiendo, te da la capacidad de modelar/programar un problema en varias 
capas, pero en ninguna parte dice que están completamente inconexas.

Ahora, si en vez de abrir_conexion(); usas mysql_connect(); en la capa 
de negocios... claro que está malo, pues vas a tener que tú mismo 
validar que la conexión se abra bien, que el nombre de usuario, que la 
password, etc. Una buena capa de manejo de datos está dada (como siempre 
digo) por adodb y MDB2 que es parte de PEAR.
>
>     ¿Existe una tercera forma?
>
>
> si y una cuarta y una quinta....etc
>
Siempre existe más de una forma de resolver estos problemas. De hecho, 
con AJAX :P
>
>     ¿Que hay de los pool de conexiones.. me comentaban que evitaban
>     estos problemas?
>
>
> No me suena, pero....
>
El pool de conexiones es "parecido" a las conexiones persistentes. Aún 
cuando no hagas conexiones persistentes, un pool de conexión te permite 
utilizar una sola conexión y abrirla/cerrarla cuando haces operaciones. 
Es algo intermedio entre conexiones open/close y persistentes. La 
conexión pool te queda abierta pero no procesando datos, sino que queda 
en modo de lock para que cuando abras otra conexion se utilice la misma 
y no una segunda o una tercera.

> Utiliza clases de acceso a datos (onda class ColegioDAO) y que estos 
> DAOs sea los encargados de abrir(no de cerrar) conexiones con la base 
> de datos. La idea es que estos DAOs se comuniquen con algun 
> DAOConnector.php y en este archivo se abran las conexiones a la base 
> de datos(o las bases de datos), asi como tambien almacenar cualquier 
> configuracion adicional de conexion este en DAOConnector. De esta 
> manera la capa de negocios solamente se entendera con los DAOs y ellos 
> verán como obtienen los datos y los empaquetaran en los Beans(crea 
> unos Beans(onda class ColegioBean) que tenga sus getters y setters(no 
> se si esta bien escrito) y que estos sean los encargados de llevar la 
> informacion empaquetada)
No crees tu capa de abstracción de datos tú mismo, no reinventes la 
rueda: ya hay unos bastante buenos, como adodb y MDB2, que ya había 
mencionado. (adodb.sourceforge.net). A pesar de que hay a quien no le 
gusta cómo programa el creador de adodb, la clase hace su pega y la hace 
bien. Aparte el sistema te queda bastante portable a Oracle, Access, SQL 
Server, MySQL, SQLite y otros... (quien va a usar PHP con SQL Server? 
bueno no falta el ... personaje)

> Ahora bien... PHP automaticamente liberará todos los resources que no 
> se esten ocupando al finalizar el script por lo que no es necesario 
> cerrar las conexiones a las bases de datos(con conexiones 
> persistentes) PHP se encargará cuando sea necesario(algo asi como un 
> recolector de basura de JAVA)
Nunca he confiado en GC... prefiero pegarme el trabajo yo solito, si es 
una linea (mysql_close($conexion);) ;)
>
>     Esto ultimo no lo he investigado
>     Agredecere cualquier colaboracion.
>     -- 
>     Juan Pablo
>
>
> saludos!
>
> -- 
> Julio Araya C.                                       Linux User #386141
> Estudiante de Ingeniería Civil Informatica           Valparaiso - Chile
> Universidad Tecnica Federico Santa Maria
> http://www.alumnos.utfsm.cl/~julio.araya 
> <http://www.alumnos.utfsm.cl/%7Ejulio.araya>
> http://www.arriendocasas.cl

------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: http://listas.inf.utfsm.cl/pipermail/php/attachments/20060209/7fdf70e4/attachment-0001.html


Más información sobre la lista de distribución PHP