Re: BUG #15170: PQtransactionStatus returns ACTIVE after Empty Commit
От | Tom Lane |
---|---|
Тема | Re: BUG #15170: PQtransactionStatus returns ACTIVE after Empty Commit |
Дата | |
Msg-id | 2588.1524663910@sss.pgh.pa.us обсуждение исходный текст |
Ответ на | Re: BUG #15170: PQtransactionStatus returns ACTIVE after Empty Commit (Rick Gabriel <klaxian@gmail.com>) |
Список | pgsql-bugs |
Rick Gabriel <klaxian@gmail.com> writes: > First, I forgot to mention that I am sending async queries (PQsendQuery). > libpq documentation states that PQgetResult() must be called repeatedly > until it returns a null pointer. Right. > Unfortunately, there is nothing about this > requirement in the official docs for PHP's libpq wrapper extension. I think you have grounds to call that a PHP documentation bug. Or at least it should be made clearer that you also need to read the libpq docs. > If I > don't call PQgetResult() one more time than I really need, the transaction > and connection statuses remain active/busy. Even though PG reports its > status as "busy", subsequent queries succeed normally. That's because if you start a new query, libpq will read-and-discard any remaining server output from the last one. That's not really a good thing to depend on though --- for example, you might miss an error message that way. > I suggest that the connection and transaction states should be updated when > all queued async queries are completed, without the extra call to > PQgetResult(). > What do you think? I think we're not going to change that, because (a) it's not a bug, it's operating as designed and documented; (b) this behavior has been stable for more than a dozen years, and changing it might well break clients expecting the current behavior; (c) it's not very clear how libpq could do that at all. I think what you're seeing is related to the fact that the server's response to a query string involves one or more query results (each containing some Data messages then a CommandComplete message), followed by a ReadyForQuery message. PQgetResult will return a PGresult when it's consumed a CommandComplete message, but you have to call it again to get libpq to consume the RFQ message --- and it's that message that causes the PQtransactionStatus result to change. Since RFQ bears the info about whether the server is truly idle or just idle-in-transaction, libpq cannot correctly update PQtransactionStatus without reading that message. You could argue that libpq should "look ahead" after reading CommandComplete to see if there's an RFQ already received, but I don't think that could be made to work reliably. You'd either have unwanted blocking in some cases, or false negatives, anytime the RFQ wasn't contained in the same TCP packet as the last CC. I doubt people would want to work with a spec that says "99% of the time PQtransactionStatus will be updated by the last real PQgetResult call, but sometimes you need one more call". regards, tom lane
В списке pgsql-bugs по дате отправления: