| 
        php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
  [2005-11-13 01:56 UTC] robertg2 at hope dot ac dot uk
 Description: ------------ Today I've been developing on a web server connecting to a remote Oracle 9i database using the latest 1.1.1 oci8 extension from PECL. Unfortunately, towards the end of the day I started receiving the Oracle error ORA-00020, indicating that the connections from the web server to the database server were not closing automatically at script execution end as I expected. 'netstat -an | grep 1521 | wc -l' on the web server reports 436 which is waaaaaay too high for a Saturday and is not representative of the load we are receiving. I understand that I am able to close the connections explicitly, but I assumed that the connections would themselves be closed automatically at end of script execution? I just installed oci8 1.1.1 yesterday and started developing on it today. Thanks, Gareth Reproduce code: --------------- In theory: <?php oci_connect($user, $password, $db); ?> and refresh a couple of hundred times. Expected result: ---------------- oci_connect($user, $password, $db) to return false with the error reported by oci_error to be ORA-00020 Actual result: -------------- not available PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             
             | 
    |||||||||||||||||||||||||||
            
                 
                Copyright © 2001-2025 The PHP GroupAll rights reserved.  | 
        Last updated: Tue Nov 04 13:00:02 2025 UTC | 
Hi there, It's now the morning, and I've verified this behaviour. <?php $conn = oci_connect("user", "pw", "db"); ?> 'netstat -an | grep 1521.*ESTABLISHED | wc -l' reports an incremented number of connections after script execution ends.Ahh Tony. Last time I touched C was in 1997... there's no debugger installed... space on /usr/local is severely limited... this PHP project has got to be finished by Wednesday... and if anything breaks again tonight it'll be my head on a stick on Monday morning. That is, I'd love to help right now but am not able to. Have reconfirmed the behaviour again. Also, thought this snippet might be of some use: <?php $conn = oci_connect("user", "pw", "db"); echo oci_close($conn); ?> oci_close($conn) returns 1 and 'netstat -an | grep 1521.*ESTABLISHED | wc -l' does NOT increment. That is, if oci_close is called the connection closes, but if it doesn't it stays open forever.Okay, for real this time: Using the 32-bit instantclient 10 doesn't seem to have an effect on the behaviour in question. <? oci_connect('user', 'pw', '//HOST/DBNAME'); ?> After browsing to a script such as this via the web, the connection to the database remains.Antony, I've looked at session cleanup. Problem 1: Incorrect order of OCISessionEnd and OCIServerDetach calls in php_oci_connection_close() The "Terminating the Application" section in chapter 2 of the OCI manual: http://download-west.oracle.com/docs/cd/B19306_01/ appdev.102/b14250/oci02bas.htm#sthref217 says to call OCISessionEnd before calling OCIServerDetach. Problem 2: In php_oci_connection_close(), connection->session is used after it has been freed. Problem 3: In php_oci_connection_close() why are there some "free" and some "efree" calls? Problem 4: In php_oci_cleanup_global_handles() the error handle should be of type OCI_HTYPE_ERROR, not OCI_HTYPE_ENV Problem 5 (minor suggestion): Calls to OCIEnvInit, OCIHandleAlloc, OCIErrorGet & OCIHandleFree in php_oci_init_global_handles() could use PHP_OCI_CALL() so debug trace is generated. Call to OCIInitialize in PHP_MINIT_FUNCTION() could use PHP_OCI_CALL(). Call to OCITerminate in PHP_MSHUTDOWN_FUNCTION() could use PHP_OCI_CALL(). A suggested patch is below. Please review and test as I may have misunderstood the solutions for problems 3 and 5, or not have taken care of some special cases. I have been unable to verify the patch solves the problem because I only see the problem on Windows, but can only build on Linux. --- oci8.c.1.283 2005-11-25 15:52:57.000000000 +1100 +++ oci8.c 2005-11-25 17:18:41.006806296 +1100 @@ -396,13 +396,13 @@ sb4 error_code = 0; text tmp_buf[PHP_OCI_ERRBUF_LEN]; - errcode = OCIEnvInit (&OCI_G(env), OCI_DEFAULT, 0, NULL); + errcode = PHP_OCI_CALL(OCIEnvInit, (&OCI_G(env), OCI_DEFAULT, 0, NULL)); if (errcode == OCI_ERROR) { goto oci_error; } - errcode = OCIHandleAlloc (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL); + errcode = PHP_OCI_CALL(OCIHandleAlloc, (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL)); if (errcode == OCI_ERROR || errcode == OCI_SUCCESS_WITH_INFO) { goto oci_error; @@ -412,7 +412,7 @@ oci_error: - OCIErrorGet(OCI_G(env), (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR); + PHP_OCI_CALL(OCIErrorGet, (OCI_G(env), (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR)); if (error_code) { int tmp_buf_len = strlen(tmp_buf); @@ -424,7 +424,7 @@ if (errcode != OCI_SUCCESS_WITH_INFO) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_ERROR: %s", tmp_buf); - OCIHandleFree((dvoid *) OCI_G(env), OCI_HTYPE_ENV); + PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(env), OCI_HTYPE_ENV)); OCI_G(env) = NULL; OCI_G(err) = NULL; @@ -441,7 +441,7 @@ static void php_oci_cleanup_global_handles(TSRMLS_D) { if (OCI_G(err)) { - PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(err), OCI_HTYPE_ENV)); + PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(err), OCI_HTYPE_ERROR)); OCI_G(err) = NULL; } @@ -480,7 +480,7 @@ #endif #if !HAVE_OCI_ENV_CREATE - OCIInitialize(PHP_OCI_INIT_MODE, NULL, NULL, NULL, NULL); + PHP_OCI_CALL(OCIInitialize, (PHP_OCI_INIT_MODE, NULL, NULL, NULL, NULL)); #endif ZEND_INIT_MODULE_GLOBALS(oci, php_oci_init_globals, NULL); @@ -609,7 +609,7 @@ #endif #if !HAVE_OCI_ENV_CREATE - OCITerminate(OCI_DEFAULT); + PHP_OCI_CALL(OCITerminate, (OCI_DEFAULT)); #endif return SUCCESS; @@ -1408,10 +1408,18 @@ } } + if (connection->svc && connection->session && connection->is_open) { + PHP_OCI_CALL(OCISessionEnd, (connection->svc, OCI_G(err), connection->session, (ub4) 0)); + } + if (connection->is_attached) { PHP_OCI_CALL(OCIServerDetach, (connection->server, OCI_G(err), OCI_DEFAULT)); } + if (connection->svc) { + PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX)); + } + if (connection->err) { PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->err, (ub4) OCI_HTYPE_ERROR)); } @@ -1424,23 +1432,15 @@ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->server, (ub4) OCI_HTYPE_SERVER)); } - if (connection->svc) { - if (connection->session && connection->is_open) { - PHP_OCI_CALL(OCISessionEnd, (connection->svc, OCI_G(err), connection->session, (ub4) 0)); - } - - PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX)); - } - if (connection->env) { PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->env, OCI_HTYPE_ENV)); } if (connection->is_persistent) { if (connection->hash_key) { - free(connection->hash_key); + efree(connection->hash_key); } - free(connection); + efree(connection); } else { if (connection->hash_key) {