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

Reply via email to