cn de en es fr jp ru
Sections: all popular

Functions:

History:

Conexiones Persistentes a Bases de Datos

Las conexiones persistentes son enlaces que no se cierran cuando la ejecución del script termina. Cuando una conexión persistente es solicitada, PHP chequea si ya existe una conexión persistente idéntica (que fuera abierta antes) - y si existe, la usa. Si no existe, crea el enlace. Una conexión "Idéntica" es una conexión que fue abierta por el mismo host, con el mismo usuario y el mismo password (donde sea aplicable).

Las personas que no estan completamente familiarizadas con como trabajan los web servers y la distribución de carga podrían equivocarse en usar conexiones persistentes para lo que no son. En particular, no le da la habilidad de abrir "sesiones de usuario" en el mismo enlace, no le da la habilidad de construir una transacción eficiente, pero no hacen muchas otras cosas más. De hecho, para ser extremadamente claros acerca de esto, las conexiones persistentes no dan cualquier otra funcionalidad que no fuera posible hacerse con sus hermanas no-persistentes.

¿Por qué?

Esto tiene que ver con la forma en que los web servers trabajan. Hay 3 formas en las cuales el web server puede generar paginas web usando PHP.

El primer método es usar PHP como una "capa" CGI. Cuando se ejecuta de esta forma, una instancia del interprete PHP es creado y destruido por cada solicitud de la página (para una página PHP) al web server. Porque es destruido después de cada solicitud, cualquier recurso que se necesite (como un enlace a un servidor de base de datos SQL) son cerradas cuando son destruidas. En este caso, no se gana nada intentando usar conexiones persistentes -- simplemente no persisten.

La segunda, y mas popular, es ejecutar PHP como un modulo en un servidor multiproceso, el cual actualmente solo incluye a Apache. Un servidor multiproceso normalmente tiene un proceso (el padre) el cual coordina un grupo de procesos (los hijos) los cuales no trabajan sirviendo páginas web. Cuando una solicitud viene desde el cliente, es manejada por uno de los hijos el cual no este sirviendo a otro cliente. Esto significa que cuando el mismo cliente hace una segunda solicitud al servidor, podría ser servido por un proceso hijo diferente a la primera vez. Cuando se abre una conexión persistente, cada petición siguiente de servicios SQL puede reusar la misma conexión establecida al servidor SQL.

El último método es usar PHP como un plug-in para un servidor web multihilos. Actualmente PHP 4 tiene soporte para ISAPI, WSAPI, y NSAPI (en Windows), los cuales permiten usar PHP como un plug-in multihilo en servidores como Nestcape FastTrack (iPlanet), Microsoft Internet Information Server (IIS), y O'Reilly's WebSite Pro. El comportamiento es esencialmente el mismo para el modelo multiproceso descrito antes.

Si las conexiones persistentes no tienen ninguna funcionalidad adicional, ¿Para que son buenas?

La respuesta es extremadamente simple -- eficiencia. Las conexiones persistentes son buenas si la sobrecarga para crear enlaces al servidor SQL son altas. Que hallan o no sobrecargas depende de muchos factores. Como, cual base de datos se usa, que sea o no la misma computadora en que esta el servidor web, así como la carga de la maquina que tiene el servidor SQL y así por el estilo. Lo esencial es que si la sobrecarga de conexiones es alta, las conexiones persistentes ayudan considerablemente. Podrían causar que los procesos hijos únicamente se conecten una vez en todo lo que duran, en lugar de que se haga cada vez que se procese una página que se conecte a un servidor SQL. Esto significa que por cada hijo que abrió una conexión persistente mantendrá una conexión persistente al servidor. Por ejemplo, si se tienen 20 procesos hijos diferentes que ejecutaran un script que hace una conexión persistente al servidor SQL, se tendrían 20 conexiones diferentes al servidor SQL, una por cada hijo.

Nótese, sin embargo, que esto puede tener algunos inconvenientes si se esta usando una base de datos con un limite de conexiones que sean excedidas por las conexiones persistentes hijas. Si la base de datos tiene un limite de 16 conexiones simultaneas, y en el curso de una sesión ocupada del servidor, 17 hilos intentan conectarse, uno no sera posible de hacerse. Si hay bugs en los scripts los cuales no contemplen los cierres de las conexiones (como un loop infinito), la base de datos con los 16 conexiones podría rápidamente hundida. Chequear la documentación de la base de datos para obtener información de como manejar conexiones abandonadas u ociosas.

Advertencia

Hay un par de advertencias mas que tener en mente cuando se usan conexiones persistentes. Una es que cuando se usan bloqueos de tablas con una conexión persistente, si el script por alguna razón no puede soltar el bloqueo, entonces los scripts subsecuentes que usan la misma conexión serán bloqueadas indefinidamente y podría ser necesario reiniciar el servidor httpd o el servidor de la base de datos. Otra cosa es que cuando se usan transacciones, una transacción bloqueada también podría llevar al siguiente script el cual usa la conexión si la ejecución del script termina antes que el bloqueo lo haga. En ese caso, se puede usar register_shutdown_function() para registrar una función de limpieza para desbloquear las tablas o deshacer la transacción. Mejor aún es evitar este problema por completo no usando conexiones persistentes en scripts los cuales usan bloqueo de tablas o transacciones (se pueden usar en otros lugares).

Un resumen importante. Las conexiones persistentes fueron diseñadas para tener conexiones normales uno a uno. Esto significa siempre que se podría ser capaz de reemplazar conexiones persistentes con conexiones no-persistentes, y no cambiaría la forma en que este se comporte. Esto podría (y probablemente lo hará) cambiar la eficiencia del script, pero no su comportamiento!.

Ver también fbsql_pconnect(), ibase_pconnect(), ifx_pconnect(), ingres_pconnect(), msql_pconnect(), mssql_pconnect(), mysql_pconnect(), ociplogon(), odbc_pconnect(), oci_pconnect(), pfsockopen(), pg_pconnect(), and sybase_pconnect().