ID:               20298
 Comment by:       phpbugs at kevin dot offwhite dot net
 Reported By:      phpbug at tab1 dot clara dot co dot uk
 Status:           Verified
 Bug Type:         ODBC related
 Operating System: *
 PHP Version:      4CVS, 5CVS (2004-04-13)
 New Comment:

Well, after some additional research I have turned up what I think is
the exact cause of the bug, but I don't feel qualified to implement the
solution.

In the php code, at line 2271 in php_odbc.c (
http://lxr.php.net/source/php-src/ext/odbc/php_odbc.c#2271 ), php calls
SQLGetInfo() passing a parameter of SQL_DATA_SOURCE_READ_ONLY to try
and determine if the connection is alive or not.  While this may work
in some odbc drivers, it is not the "official" way of asking if the
connection is dead.  According to my driver supplier (
http://www-912.ibm.com/o_dir/odbcforum.nsf/8178b1c14b1e9b6b8525624f0062fe9f/B0CFDBA3D8DBAC0F86256EA80077D2B9?OpenDocument
) and the Microsoft's ODBC Programmer's reference (
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcodbc_connection_pooling.asp
), the correct method is to use SQLGetConnectAttr() to check the
Attribute SQL_ATTR_CONNECTION_DEAD.


Steps to reproduce:
  1) Use PHP's odbc_pconnect() function with the iSeries ODBC Driver
for Linux.
  2) Allow the connection to idle long enough for the Server to
disconnect.
  3) Try and use the connection which was disconnected by the server.

Expected result:
1)  PHP calls SQLGetConnectAttr() to check SQL_ATTR_CONNECTION_DEAD,
which returns SQL_ERROR.  
2) PHP removes the connection from its internal list, creates a new
persistent connection, and returns that new connection to the php
script
3) call to odbc_exec() succeeds.

Actual result:
1) PHP calls SQLGetInfo() to check SQL_DATA_SOURCE_READ_ONLY, which
returns SQL_SUCCESS
2) PHP believes this to be a valid connection, and returns this
connection to the php script
3) call to odbc_exec() fails.


Previous Comments:
------------------------------------------------------------------------

[2004-04-02 10:48:58] phpbugs at kevin dot offwhite dot net

I'm seeing this problem on a Red Hat 9 system running PHP 4.3.5 on
Apache 2.0.

I have check_persistent and allow_persistent On, and phpinfo() reports
1 active persistent link.  I'm not clear if the problem is in the ODBC
Driver not reporting back to php that the server has terminated the
link, or if PHP is not properly checking if the persistent link needs
to be re-established, but I thought it wouldn't hurt to report the bug
here and see what we can come up with.

An interesting thing is that while phpinfo() reports only one
persistent link, a netstat on the webserver shows 6 connections to the
database server.  When I load the page with the odbc_pconnect call, it
will alternate between working and not working from pageload to
pageload, so it seems that some of those connections are good and
others are not, and php is not removing the bad connection from the
hash list.

The error message I get is:
Warning: odbc_exec(): SQL error: [unixODBC][IBM][iSeries Access ODBC
Driver]Communication link failure. comm rc=10054 - CWBCO1047 - The
iSeries server application disconnected the connection, SQL state 08S01
in SQLExecDirect in /usr/local/apache/htdocs/test.php on line 15

------------------------------------------------------------------------

[2003-12-02 04:47:47] phpbug at tab1 dot clara dot co dot uk

okay this was tested with: php4-win32-STABLE-200312020930

1st run:
resource(2) of type (odbc link persistent)

followed by the correct query results

2nd run (after killing db connection):

resource(1) of type (odbc link persistent)

Warning: odbc_exec(): SQL error: [Informix][Informix ODBC
Driver]Communication link failure., SQL state 08S01 in SQLExecDirect in
C:\InetPub\wwwroot\test.php on line 8

------------------------------------------------------------------------

[2003-12-01 03:00:17] [EMAIL PROTECTED]

Can you add 'var_dump($dbconn);' after that odbc_pconnect() call..?
What does it output? (in the re-run)


------------------------------------------------------------------------

[2003-02-20 04:58:12] t_o_m_ at yahoo dot com

Having reread all of this I see that nowhere have I mentioned I'm using
IIS (ISAPI) not Apache, if that makes a difference? I thought when I
put Windows in the OS box whoever read it would assume IIS.

In answer to your question "no", the behaviour is the same if
odbc.check_persistent is on or off.
The point is when it is off I would expect it to be my responsibility
to check the connection and would expect the error if I did not.
I would expect that when odbc.check_persistent was on odbc_pconnect was
supposed to check the connection for me if the connection it is about
to return from its pool is dead then it should discard it and create a
new one as when the pool is empty. Which is clearly not happening.

------------------------------------------------------------------------

[2003-02-18 12:01:03] [EMAIL PROTECTED]

Well the nature of CGI doesn't really lend itself to supporting
persistant connections.  It's run when requested and then exited after
that.  So no data can really presist between pages that exists solely
in the CGI.  

So this behavior only exists when odbc.check_persistent is turned on?

------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/20298

-- 
Edit this bug report at http://bugs.php.net/?id=20298&edit=1

Reply via email to