ID: 33159
Updated by: [EMAIL PROTECTED]
Reported By: henning dot mohren at gmx dot de
-Status: Open
+Status: Assigned
Bug Type: OCI8 related
Operating System: Solaris 9
-PHP Version: 5.0.4
+PHP Version: 5.0.4, 4.3.11
-Assigned To:
+Assigned To: tony2001
Previous Comments:
------------------------------------------------------------------------
[2005-05-27 07:53:51] henning dot mohren at gmx dot de
Description:
------------
We have several web-based php-db-applications in use. In case of
db-maintenance (when the db is down), the applications (of course) fail
to deliver db contents. After restarting the db, the web-application
still cannot connect to the db. A webserver restart is required. For
me, this seems to be a bug related oci8-clients (I'm using oracle
instant client as well as the older oracle 9 client) or PHP.
So I reported this problem to Oracle Support and I got the suggestion
to fix the problem in PHP.
Expected result:
----------------
Here is Oracle's solution:
I have received your request and will try to help you.
First of all there are two ways in OCI8 and higher to establish a
connection
1. Design for optimized Access against one or multiple DBs by splitting
up the "Connect" into Access path (he Library loading etc) and one or
multiple Sessions
OCIServerAttach()
OCISessionBegin()
-- OCI DB ACCESS --
OCISessionEnd()
....
OCISessionBegin()
-- OCI DB ACCESS --
OCISessionEnd()
OCIServerDetach()
This Design allows to switch between Servers and Sessions
2. "Plain" Design -
OCILogon()
-- OCI DB ACCESS --
OCILogoff()
furtheron, I have downloaded the source of PHP and checked
where the connect is established. As you can see, ocilogon() uses the
first "smart" way - enabling to remember if a previously server was
attached by retrieving the hash values:
ocilogon --> oci_connect --> oci_do_connect
static void oci_do_connect(INTERNAL_FUNCTION_PARAMETERS,int
persistent,int exclusive)
......
connection = (oci_connection *) ecalloc(1,sizeof(oci_connection));
if (!connection) {
goto CLEANUP;
}
server = _oci_open_server(dbname,persistent);
if (!server) {
goto CLEANUP;
}
if (exclusive) {
/* exlusive session can never be persistent!*/
persistent = 0;
} else {
/* if our server-context is not persistent we can't */
persistent = (server->persistent) ? persistent : 0;
}
session =
_oci_open_session(server,username,password,persistent,exclusive,charset);
.............
static oci_server *_oci_open_server(char *dbname,int persistent)
{
oci_server *server, *pserver = NULL;
TSRMLS_FETCH();
/*
check if we already have this server open
we will reuse servers within a request no matter if the user requested
persistent connections or not!
but only as pesistent requested connections will be kept between
requests!
*/
/* TODO either keep servers global or don't reuse them at all */
zend_ts_hash_find(persistent_servers, dbname, strlen(dbname)+1, (void
**) &pserver);
.......
CALL_OCI_RETURN(OCI(error),
OCIServerAttach(
server->pServer,
OCI(pError),
(text*)server->dbname,
strlen(server->dbname),
(ub4) OCI_DEFAULT
)
);
Unfortunatly, there is no "force" parameter which can be used to force
a ServerAttach - nor supports PHP the second, plain way for dumb
Logon/Logoff.
for my opinion this is a PHP Bug and a fix would be to put
a while clause (3 Attempts) round ServerAttach / SessionBegin to allow
a forced ServerAttach if Hash code states server is available - but DB
was bounced - resulting in lost server context.
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=33159&edit=1