Il est un symptôme de pg_send_query()
ne pas être en mesure de passer avec succès la connexion au mode de blocage. En regardant le code source dans phps pgsql.c, vous pouvez trouver:
/* {{{ proto bool pg_send_query(resource connection, string query)
Send asynchronous query */
PHP_FUNCTION(pg_send_query)
{
<... snipped function setup stuff ...>
if (PQ_SETNONBLOCKING(pgsql, 1)) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode");
RETURN_FALSE;
}
<... snipped main function execution stuff ...>
if (PQ_SETNONBLOCKING(pgsql, 0)) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode");
}
RETURN_TRUE;
}
Ainsi, l'erreur est soulevée à la fin de la fonction, après le travail principal est fait. Cela correspond à votre observation que vos instructions INSERT sont exécutées. L'objectif des deux appels PQ_SETNONBLOCKING
est de mettre la connexion en mode non bloquant pour permettre l'exécution asynchrone et de rétablir ensuite le comportement de blocage par défaut. De l'documentation of PQsetnonblocking: (PQ_SETNONBLOCKING est juste un alias défini pour cette fonction):
Sets the nonblocking status of the connection.
int PQsetnonblocking(PGconn *conn, int arg);
Sets the state of the connection to nonblocking if arg is 1, or blocking if arg is 0. Returns 0 if OK, -1 if error.
In the nonblocking state, calls to PQsendQuery, PQputline, PQputnbytes, and PQendcopy will not block but instead return an error if they need to be called again.
Note that PQexec does not honor nonblocking mode; if it is called, it will act in blocking fashion anyway.
En regardant plus à la source de PQsetnonblocking (en PostgeSQLs fe-exec.c), il y a deux raisons possibles pour lesquelles l'appel pourrait échouer :
/* PQsetnonblocking:
* sets the PGconn's database connection non-blocking if the arg is TRUE
* or makes it non-blocking if the arg is FALSE, this will not protect
* you from PQexec(), you'll only be safe when using the non-blocking API.
* Needs to be called only on a connected database connection.
*/
int
PQsetnonblocking(PGconn *conn, int arg)
{
bool barg;
if (!conn || conn->status == CONNECTION_BAD)
return -1;
barg = (arg ? TRUE : FALSE);
/* early out if the socket is already in the state requested */
if (barg == conn->nonblocking)
return 0;
/*
* to guarantee constancy for flushing/query/result-polling behavior we
* need to flush the send queue at this point in order to guarantee proper
* behavior. this is ok because either they are making a transition _from_
* or _to_ blocking mode, either way we can block them.
*/
/* if we are going from blocking to non-blocking flush here */
if (pqFlush(conn))
return -1;
conn->nonblocking = barg;
return 0;
}
donc, soit la connexion se sont perdus en quelque sorte, ou PQflush n'a pas fini avec succès, ce qui indique des choses qui reste dans la mémoire tampon de sortie de connexion.
Le premier cas serait inoffensif, car votre script remarquerait certainement la perte de connexion pour les appels ultérieurs et réagirait à cela (ou échouerait plus perceptible).Ceci laisse le deuxième cas, ce qui signifie que vous avez une connexion à l'état non par défaut, non bloquant. Je ne sais pas si cela pourrait affecter les appels ultérieurs qui réutiliseraient cette connexion. Si vous voulez jouer en toute sécurité, vous fermez la connexion dans ce cas et utilisez un nouveau/autre.
+1 pour aller directement à la source –
+1 pour identifier les causes réelles et faire des suggestions pratiques sur ce qu'il faut faire. Bien joué! –
Je pense que j'ai malheureusement réussi à répéter cette erreur avec pg_query() combiné avec pg_pconnect(). L'utilisation de pg_send_query() n'est pas requise. La requête pg_query semble générer aléatoirement cette erreur si la connexion précédente a été automatiquement annulée lorsque la nouvelle connexion est acquise avec pg_pconnect(). Problème était visible avec PHP 5.3.2 et Postgres 8.4 fonctionnant sur Ubuntu 10.04 LTS x86-64. –