首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >终止用户中止时的MySQL查询

问终止用户中止时的MySQL查询
EN

Stack Overflow用户
提问于 2011-09-28 11:25:45
回答 7查看 9.5K关注 0票数 14

当从PHP运行长查询时,如果用户在浏览器中按下停止,如何关闭查询?

考虑到我不能调用任何其他PHP函数,因为PHP在等待MySQL时被阻塞。

此外,由于会话锁定,我不能再向服务器(通过Ajax)发出任何请求。

因此,一个解决办法可以是:

  • 忽略用户中止
  • 在后台运行长查询,如果完成的话,让PHP每100 it检查一次
  • 从查询中获取pid
  • 如果用户中止,则关闭pid。
  • 否则在完成后返回结果。

我不知道该怎么做的两件事是:

  • 运行非阻塞(背景)查询
  • 获取查询的pid
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-09-28 14:21:32

对于那些感兴趣的人,我用的是:

代码语言:javascript
复制
<?php
// Connection to query on
$query_con = mysqli_connect($host, $user, $password, $name, $port);

// Connection to kill on
$kill_con = mysqli_connect($host, $user, $password, $name, $port);

// Start the query
$query_con->query($slow_query, MYSQLI_ASYNC);

// Get the PID
$thread_id = $query_con->thread_id;

// Ignore user abort so we can kill the query
ignore_user_abort(true);

do  {
    // Poll MySQL
    $links = $errors = $reject = array($mysqli->mysqli);
    $poll = mysqli_poll($links, $errors, $reject, 0, 500000);

    // Check if the connection is aborted and the query was killed
    if (connection_aborted() && mysqli_kill($kill_con, $thread_id)) {
        die();
    }
} while (!$poll);

// Not aborted, so do stuff with the result
$result = $link->reap_async_query();
if (is_object($result)) {
    // Select
    while ($row = $result->fetch_object()) {
        var_dump($row);
    }
} else {
    // Insert/update/delete
    var_dump($result);
}
票数 18
EN

Stack Overflow用户

发布于 2011-09-28 11:28:48

一旦PHP注意到用户已经停止了请求(在脚本试图向用户输出某些内容之前通常不会发生这种情况),您的脚本就会终止。在关闭之前,PHP调用已激活的任何关闭函数。您可以实现终止查询的关闭函数,并将其注册到register_shutdown_function()。

您可以这样做的另一种方法是在打开ignore_user_abort()的情况下运行脚本,并通过定期调用connection_aborted()来检查用户是否已中止。如果用户已中止,则终止查询并优雅地退出脚本。

有关连接处理这里的更多信息。

票数 5
EN

Stack Overflow用户

发布于 2011-09-28 13:04:34

如果查询所花费的时间是由于返回的大型数据集造成的,则可以使用mysql_unbuffered_query。然后在shutdown_function中,您可以释放结果并从mysql断开连接。

如果您正在使用PHP5.3.x并拥有mysqlnd,您可能可以在mysqli_query中使用MYSQLI_ASYNC,然后使用mysqli_poll来获得结果。

第一个选项只有在检索数据集所花费的时间时才会有所帮助。但是,如果mysql在解析和创建执行计划以及将表加载到内存方面实际上花费了很长时间,那么它不会有帮助。在这种情况下,您需要MYSQLI_ASYNC,它只在PHP 5.3.x和mysqlnd上可用。

另外,如果您的主要问题是session locking,请查看本文中的PHP文档http://php.net/manual/en/ref.session.php#64525

你可能会在那里找到一些有用的建议。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7582485

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档