pg_send_query (): не Может установить соединение с блокирующимся режимом?

C не имеет вложенных функций. Вложенные функции GCC являются расширением языка.

Ваша ошибка во время выполнения в GCC является орфографической ошибкой. inner_funcion должно быть inner_function.

12
задан Frank Farmer 19 September 2013 в 17:38
поделиться

2 ответа

Это признак того, что pg_send_query () не может успешно переключить соединение обратно в режим блокировки. Глядя на исходный код PHP pgsql.c, вы можете найти:

/* {{{ 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;
}

Таким образом, ошибка возникает в конце функции, после того, как основная работа сделана. Это согласуется с вашим наблюдением, что ваши инструкции INSERT выполняются.

Вся цель двух вызовов PQ_SETNONBLOCKING состоит в том, чтобы перевести соединение в неблокирующий режим, чтобы разрешить асинхронное выполнение, и вернуть его к блокировке по умолчанию поведение потом. Из документации PQsetnonblocking : (PQ_SETNONBLOCKING - это просто псевдоним, определенный для этой функции):

Устанавливает неблокирующий статус для соединение.

 int PQsetnonblocking (PGconn * conn, int arg);

Устанавливает состояние соединения как неблокирующее, если arg равен 1, или блокировка, если arg равен 0. Возвращает 0, если ОК, -1 в случае ошибки.

В неблокирующем состоянии вызывает PQsendQuery, PQputline, PQputnbytes, и PQendcopy не будет блокировать, но вместо этого верните ошибку, если им нужно для повторного вызова.

Обратите внимание, что PQexec не выполняет неблокирующий режим; если это называется, это в любом случае будет действовать блокирующим образом.

Если посмотреть дальше на источник PQsetnonblocking (в PostgeSQLs fe-exec.c), есть две возможные причины, по которым вызов может завершиться неудачно:

/* 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;
}

Итак, либо соединение каким-то образом потеряно, либо pqFlush не завершился успешно, что указывает на остаток материала в выходном буфере соединения.

Первый случай будет безвредным, так как ваш сценарий обязательно заметит потерянное соединение для последующих вызовов и отреагирует на это (или сбой станет более заметным).

] Остается второй случай, который будет означать, что у вас соединение в нестандартном, неблокирующем состоянии. Я не знаю, может ли это повлиять на последующие вызовы, которые будут повторно использовать это соединение. Если вы хотите перестраховаться, закройте соединение в этом случае и используйте новое / другое.

24
ответ дан 2 December 2019 в 04:09
поделиться

Похоже, вы пытаетесь использовать функцию pg_send_query () для отправки асинхронных запросов в PostgreSQL. Цель этой функции - позволить вашему PHP-скрипту продолжить выполнение другого кода, ожидая, пока PostgreSQL выполнит ваш запрос и подготовит результат.

Пример, приведенный в документах для pg_send_query () , предполагает, что вы не должны отправлять запрос, если PostgreSQL уже переваривает другой запрос:

if (!pg_connection_busy($dbconn)) {
  pg_send_query($dbconn, "select * from authors; select count(*) from authors;");
}

Есть ли причина вы используете pg_send_query () вместо pg_query () ? Если вы можете разрешить своему сценарию блокировать ожидание выполнения запроса, я предполагаю (правда, не пробуя его), что вы не увидите этих ошибок.

3
ответ дан 2 December 2019 в 04:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: