能否通过PDO查询当前是否存在活跃数据库查询?
能否通过PDO查询当前是否存在活跃数据库查询?
答案 = 不能
你可以尝试执行这条语句,说不定在你的场景下能缓解问题:
setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY , true);
另外,在可疑方法后调用->closeCursor()可能会有帮助,但你需要针对类似这样的用法编写适配代码:
return $pdoStatement->rowCount()===1;
高风险/可疑方法清单:
->quote() 如果像mysql_real_escape_string()那样使用连接,则有轻微风险 ->query() 高风险 - 需调用->closeCursor() ->fetch() 最高风险 - 需调用->closeCursor() ->fetchAll() 应该安全,但Stack Overflow上有相关报错反馈 ->rowCount() **这个**是导致我问题的原因
排查bug的实操步骤:
- 在触发致命错误的代码行之前调用
debug_backtrace() - 根据返回的调用栈回溯执行流程,在每个可疑方法前添加
->closeCursor(),保存后测试 - 如果仍出现致命错误,就逐个修复下一个可疑方法
- 找到出错的代码行后,移除
debug_backtrace()
如果这还不行,那问题肯定出在某个你没注意到的执行路径上,我暂时也没有其他办法了。
PHP PDO MySQL未修复的相关Bug
这些问题目前似乎被官方忽略了:
- Bug #70066:意外出现"Cannot execute queries while other unbuffered queries"错误,状态为未关闭。临时解决方案是用
exec()替代query(),但我认为这是个bug——因为触发错误时并没有其他活跃查询。 - Bug #71145:初始化命令中的多条语句触发无缓冲查询错误,状态为未关闭。临时解决方案是使用单条初始化语句:
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci, SESSION sql_mode=traditional; - Bug #74584:意外触发关于活跃无缓冲查询的错误,状态为未关闭。触发条件:
- 必须关闭模拟预处理
- 使用"LOCK TABLE"会触发错误,但执行"set @foo='bar'"这类语句则不会
我目前也不清楚这种场景下错误出现的原因。
重要提示
该错误是致命错误,意味着:
- 程序会直接终止运行
- 无法通过
try(){}catch($e){}代码块捕获处理
对应的错误信息如下,能帮你定位修复方向:
"General error: 2014 Cannot execute queries while other unbuffered queries are active"
希望这些内容能帮你省去遍历整个代码库找bug的麻烦。
我自己目前正在解决一个特殊场景:错误由这条代码触发:
$statement = pdo->prepare( $sql );
也就是说错误出现在prepare()阶段,而不是大家常见的query()、fetch()、fetchAll()或者->bind(':name' , $value , PDO::PARAM_STR)步骤——这意味着我收到错误信息时,根本没有在"执行查询"。
我特意整理这些内容,是因为Stack Overflow上有很多关于该错误的提问,但都没有针对性的解决方案。另外,我尝试过以下方法,均无效:
$pdo->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY , true);
$pdo->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY , false); // 死马当活马医试了下
内容的提问来源于stack exchange,提问作者John Griffiths

