ID:               31411
 Comment by:       yohgaki at ohgaki dot net
 Reported By:      mike at ecommerce dot com
 Status:           Open
 Bug Type:         PostgreSQL related
 Operating System: *
 PHP Version:      4.3.10
 New Comment:

The best way to fix this problem is "hendle broken persistent
connections w/o errors in pgsql module".  For the time being, I suggest
to use @ operator or define your error handler so that the error is
ignored.


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

[2005-01-12 06:23:08] [EMAIL PROTECTED]

Er...yeah. Heh, shouldn't moderate when I'm distracted.

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

[2005-01-05 18:47:46] mike at ecommerce dot com

> #if HAVE_PQSETNONBLOCKING
> #define PQ_SETNONBLOCKING(pg_link, flag) \
>     PQsetnonblocking(pg_link, flag)
> #else
> #define PQ_SETNONBLOCKING(pg_link, flag) 0
> #endif
>
> More than one reason PQ_SETNONBLOCKING would fail...

Not really. Zero means "no error".

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

[2005-01-04 23:49:44] [EMAIL PROTECTED]

#if HAVE_PQSETNONBLOCKING
#define PQ_SETNONBLOCKING(pg_link, flag) \
    PQsetnonblocking(pg_link, flag)
#else
#define PQ_SETNONBLOCKING(pg_link, flag) 0
#endif

More than one reason PQ_SETNONBLOCKING would fail...

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

[2005-01-04 22:39:30] mike at ecommerce dot com

Description:
------------
Problem Description:
I have an issue with a functionality in the function
_rollback_transactions defined in ext/pgsql/pgsql.c. This function is
responsible to rollback all transaction that are currently open in
persistent database connections, so those transactions do not leak over
to following scripts.

Before it sends any commands over the connection, it does the
following:

if (PQ_SETNONBLOCKING(link, 0)) {
    php_error_docref("ref.pgsql" TSRMLS_CC, E_NOTICE, "Cannot set
connection to blocking mode");
    return -1;
}

When this "Cannot set connection to blocking mode" error is raised,
then in almost all cases it is because the connection to the database
server is broken, maybe because the PostgreSQL server was restarted, or
the network connection to it broke.

The problem is not the error message, because if something is wrong
with the database connection, it is correct to print an error (or to
call the error handler).

The problem is that in this special case this error message is not
displayed in the script that opened the database connection, but rather
in the first script this is run after the persistent connection broke.
This can be a script that is executed sometime afterwards - maybe a
long time afterwards, maybe in a script that never opened a database
connection. Basically it could occur in scripts that would normally not
cause an error at all. My point is that cause and effect of the error
are disconnected.

Real-Life example:
The company i work for has this problem currently in one of our
applications. We use persistent connections to a PostgreSQL database
over an unreliable internet connection, that breaks every now and then.
Normally, this is not a big deal, because we have local database caches
which is used as a failsafe solution, and all scripts are programmed in
a way to watch out for database errors and automatically re-connect to
this failsafe database without the user noticing a thing. All fine
until now.

But every time the internet connection - and therefore the connection
to the remote database - breaks, all other PHP applications that are
hosted on the same server, which do use different databases or do not
use a database at all, suddenly print the message "Notice: (null)():
Cannot set connection to blocking mode in Unknown on line 0" at the end
of the output.

Suggested Resolution:
Remove the line that calls php_error_docref to raise the error. The
database link is removed anyway from the list of persistent
connections, due to the "return -1;" directly afterwards.

I am aware that there are other solutions, like adjusting
"error_reporting" not to include E_NOTICE, or to turn off
"display_errors". Or to install a custom error handler that silently
ignores this error.

However, after carefully considering all options, IMHO i think that
removing the line in the PHP sources that raises the error is the
cleanest solution, with the main argument for it being that cause and
effect of the problem do not directly relate. That means the script
that prints the error and/or handles the error in its custom error
handler may have nothing to do with the broken database connection.


Actual result:
--------------
Notice: (null)(): Cannot set connection to blocking mode in Unknown on
line 0


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


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

Reply via email to