La extenisón OCI8 proporciona tres funciones diferentes para conectarse a Oracle. La función de conexión estándar es oci_connect(). Ésta crea una conexión a una base de datos de Oracle y devuelve un recurso utilizado por las llamadas subsiguientes a dicha base de datos.
Conectarse a un servidor Oracle es una operación razonablemente cara en términos del tiempo que toma en completarse. La función oci_pconnect() utiliza una caché de conexiones persistentes que puede ser reutilizada a través de diferentes peticiones de scripts. Esto significa que una conexión únicamente tendrá carga adicional normalmente una vez por cada proceso de PHP (o subproceso de Apache).
Si una aplicación se conecta a Oracle usando un conjunto diferente de credenciales para cada usuario de la web, la caché persistente empleada por oci_pconnect() no será muy útil ya que el número de usuarios concurrentes aumentará, hasta el punto donde podría empezar a afectar negativamente al rendimiendo global del servidor de Oracle debido a que mantiene demasiadas conexiones inactivas. Si la aplicación está estructurada de esta manera, se recomienda ajustarla a través de las opciones de configuración oci8.max_persistent y oci8.persistent_timeout (éstas otorgan control sobre el tamaño y el tiempo de vida de la caché de conexiones persistentes), usar Oracle Database Resident Connection Pooling (en Oracle Database 11g o posterior), o usar oci_connect() en su lugar.
oci_connect() y oci_pconnect() emplean una caché de conexiones; si mútiples llamadas a oci_connect() usan los mismos parámetros en un script dado, la segunda y subsiguientes llamadas devolverán el gestor de conexión existente. La caché usada por oci_connect() se limpia al final de la ejecución del script, o cuando se cierra explícitamente el gestor de conexión. La función oci_pconnect() tiene un comportamiento similar, aunque su caché se mantiene de forma separada y sobrevive entre peticiones HTTP.
Esta característica de almacenamiento en caché significa que dos gestores no están transaccionalmente aislados (de hecho, son el mismo gestor de conexión, por lo que no existe aislamiento alguno). Si la aplicación necesita dos conexiones transaccionalmente aisladas por separado, se ha de usar oci_new_connect().
La caché de oci_pconnect() es limpiada y cualquier conexión a bases de datos cerrada cuando finaliza el proceso de PHP, por lo que el uso efectivo de conexiones persistentes requiere que PHP sea un módulo de Apache o se use con FGCI, o similar. Las conexiones persistentes no tendrán ningún beneficio con oci_connect() cuando PHP se use con CGI o mediante la línea de comandos.
La función oci_new_connect() siempre crea una nueva conexión al servidor de Oracle, independientemente de que existan otras conexiones. Las aplicaciones web con mucho tráfico deberían evitar el uso de oci_new_connect(), especialmente las secciones más concurridas de la aplicación.
PHP, desde 5.3 (PECL OCI8 1.3), posee soporte para Oracle Database Resident Connection Pooling (DRCP). DRCP permite el uso más eficiente de la memoria de la máquina donde reside la base de datos y proporciona una alta escalabilidad. Se requiren cambios mínimos, o ninguno, en la aplicación para usar DRCP.
DRCP es apropiado para aplicaciones que se conectan usando pocos esquemas de bases de datos y mantienen abiertas dichas conexiones durante un corto periodo de tiempo. Las demás aplicaciones deberían usar los procesos de servidor de bases de datos predeterminado Dedicado de Oracle, o usar servidores Compartidos.
DRCP beneficia a las tres funciones de conexión, pero proporciona la mayor escalabilidad cuando las conexiones se crean con oci_pconnect().
Para que DRCP esté disponible en OCI8, las bibliotecas cliente de Oracle usadas por PHP y la versión de Oracle Database deben ser 11g o superior.
La documentación de DRCP se encuentra en varios manuales de Oracle. Por ejemplo, véase » Configuring Database Resident Connection Pooling en la documentación de Oracle para obtner información de su uso. Un » Libro blanco de DRCP contiene información de antecedentes sobre DRCP.
Para usar DRCP, construya PHP con la extensión OCI8 1.3 (o posterior) y las bibliotecas de Oracle 11g (o posteriores), y luego siga estos pasos:
Como administrador de bases de datos privilegiado, use un programa como SQL*Plus para iniciar el agrupamiento de conexiones en la base de datos:
SQL> execute dbms_connection_pool.start_pool;
Opcionalmente use dbms_connection_pool.alter_param() para configurar los ajustes de DRCP. La configuración de la agrupación actual se puede consultar desde la vista DBA_CPOOL_INFO.
Actualice las cadenas de conexión usadas. Para las aplicaciones de PHP que actualmente se conecten usando un Nombre de Conexión de Red como MYDB:
$c = oci_pconnect("mi_usuario", "mi_contraseña", "MYDB");
Modifique el fichero tnsnames.ora y añada una cláusula (SERVER=POOLED), por ejemplo:
MYDB = (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp) (HOST=myhost.dom.com) (PORT=1521))(CONNECT_DATA=(SERVICE_NAME=sales) (SERVER=POOLED)))
Alternativamente, modifique la sintaxis de Easy Connect en PHP y añada :POOLED después del nombre del servidor:
$c = oci_pconnect("mi_usuario", "mi_contraseña", "mi_host.dom.com:1521/sales:POOLED");
Edite php.ini y elija un nombre de clase de conexión. Este nombre señala una división lógica de la agrupación de conexiones y se puede usar para aislar la agrupación para diferentes aplicaciones. Cualquier aplicación de PHP con el mismo nombre de usuario y valor de clase de conexión podrá compartir conexiones de la agrupación, proporcionando una mayor escalabilidad.
oci8.connection_class = "NOMBRE_DE_MI_APLICACIÓN"
Ejecute la aplicación, conectándose a la base de datos 11g (o posterior).
Nota:
Las aplicaciones que usen Oracle 10g que requieran el rendimiento de conexiones persitentes, pueden reducir la cantidad de memoria que el servidor de bases de datos use utilizando sevidores Compartidos de Oracle (anteriormente conocidos como Servidores de Multisubprocesos). Consulte la documentación de Oracle para más información.
El cambio de una contraseña con conexiones DRCP fallará con el error ORA-56609: Usage not supported with DRCP. Ésta es una restricción documentada de Oracle Database 11g.
Con la extensión OCI8 1.3, las conexiones persistentas pueden ser cerradas por el usuario, permitiendo mayor control sobre el uso de recursos de conexión. Las conexiones persistentes ahora también serán cerradas automáticamente cuando no haya variables de PHP que hagan referncia a ellas, como al final del ámbito de una función de usuario de PHP. Esto revertirá cualquier transacción no consignada. Estos cambios a las conexiones persistentes hacen que se comporten de forma similar a las conexiones no persistentes, simplificando la interfaz, permitiendo así mayor consistencia y predictabilidad a las aplicaciones. Use oci8.old_oci_close_semantics con el valor de On para conservar el comportamiento histórico.
Si Oracle Database es la versión 11.1.0.6, se deben aplicar los parches de las bases de datos de Oracle para el error 6474441 de Oracle para usar DRCP. Sin este parche, los errores como ORA-01000: maximum open cursors exceeded, ORA-01001 invalid cursor o ORA-01002 fetch out of sequence podrían ocurrir. Este error fue corregido en Oracle 11.1.0.7 en adelante.
Si no se puede aplicar el parche de las bases de datos de Oracle 11.1.0.6, se pueden seguir una de estas tres alternativas en su lugar:
Los parches Oracle Database 11.1.0.7 y Oracle Database 11.1.0.6 para el error 6474441 de Oracle permiten a las aplicacinones de PHP con conexión DRCP usar el disparador LOGON de la base de datos para establecer las propiedades de una sesión en el momento de crearla. Ejemplo de tales configuraciones son el lenguaje NLS y el formato de fecha.
Si no se puede aplicar el parche para bases de datos Oracle 11.1.0.6, se pueden seguir las siguientes alternativas en lugar de usar los disparadores LOGON:
El reestableciemiento automático de las conexiones persistentes de PHP después de la regeneración de procesos de Apache o FGCI significa que únicamente se recomiendan los disparadores LOGON de PHP para establecer los atributos de sesiones y no para peticiones de conexiones de usuario por cada aplicación. Esto es incluso más recomendado con DRCP debido al ajuste automático de la agrupación y a la manera de desencadenar los disparadores LOGON con la autenticación de DRCP.