【问题标题】:PHP Open Multiple ConnectionsPHP打开多个连接
【发布时间】:2013-04-25 15:02:53
【问题描述】:

我想在不同的浏览器选项卡中运行同一脚本的多个脚本实例。我希望他们有不同的 MySQL 连接。每个都有其独特的联系。

我知道mysql_connect 有第四个参数$new_link 应该打开一个新链接,但即使这样通常也不会打开一个新连接。有时确实如此。

我在 Widows 机器上安装了 XAMPP。

问题是:我如何绝对强制 PHP/MySQL 为脚本的每个实例打开一个新连接?脚本运行大约 2 分钟。

http://localhost/myscript.php

这里是 MySQL 代码的摘录。首先从数据库加载一个工作分配并将其标记为进行中:

public function loadRange() {
    try{
        $this->db()->query('START TRANSACTION');
        $this->row = $this->db()->getObject("
            SELECT * FROM {$this->tableRanges}
            WHERE
                status = " . self::STATUS_READY_FOR_WORK . "
                AND domain_id = {$this->domainId}
            ORDER BY sort ASC
            LIMIT 1");
        if(!$this->row) throw new Exception('Could not load range');
        $this->db()->update($this->tableRanges, $this->row->id, array(
            'thread_id' => $this->id,
            'status' => self::STATUS_WORKING,
            'run_name' => $this->runName,
            'time_started' => time(),
        ));
        $this->db()->query('COMMIT');
    } catch(Exception $e) {
        $this->db()->query('ROLLBACK');
        throw new Exception($e->getMessage());
    }
}

然后脚本可能会也可能不会根据它找到的内容在另一个表中插入行。

最后,当任务完成时,分配行再次更新:

    $this->db()->update($this->tableRanges, $this->row->id, array(
        'status' => self::STATUS_EXECUTED,
        'time_finished' => time(),
        'count' => $count,
    ));

特别是$this->tableRanges 表看起来被锁定了。知道为什么会这样吗?它是一个 InnoDB 表。

【问题讨论】:

  • 每个实例的新连接是标准行为。您是否正在尝试寻找解决方案的具体问题?

标签: php mysql xampp


【解决方案1】:

我想在不同的浏览器选项卡中运行同一脚本的多个脚本实例。我希望他们有不同的 MySQL 连接。每个都有其独特的联系。

其实就是这样,不需要任何额外的努力

问题是:如何绝对强制 PHP/MySQL 为脚本的每个实例打开一个新连接。

答案:什么都不做:)

【讨论】:

  • 不,脚本运行了大约 2 分钟,我看到一个等待另一个完成,我从 MySQL 看到只有一个连接一直打开: SHOW STATUS LIKE '%onn% '
  • 在这种情况下,听起来你的表正在锁定,而 sql 查询完成。
  • 你使用表锁吗? my.cnf 允许多少个并行连接?您是否使用root 帐户进行连接?
  • 看起来您正面临单线程浏览器的限制。尝试 Chrome 并再次检查脚本行为;)
  • @castis 是的,对我来说也是如此,但表是 InnoDB,我执行 START TRANSACTION、SELECT、UPDATE、COMMIT
【解决方案2】:

每次您点击http://localhost/myscript.php 时都会运行一个新实例。该实例的所有内容都是唯一的,Web 服务器生成一个新的 PHP 线程,其中所有资源、连接、变量都是唯一的。

只有sessions 之类的状态管理设备是共享的,如果您在同一浏览器中使用不同的选项卡,也是如此。不同浏览器点击同一个URL,状态管理资源也不同。

要回答您的问题,就像之前提到的其他人一样 - 如果您使用 mysql_connect,则每个实例的连接都不同。您可以创建一个在应用程序退出时不会关闭的持久连接,并使用mysql_pconnect 为新的连接请求创建reuses。但是在您的代码中,您似乎使用的是后者,在这种情况下,您很好。

您可以尝试设置隔离读取级别,以防止在读取选择时表停顿

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;

More information can be found here.

我想还是要花点时间才能找到最有效的选项。

【讨论】:

  • 我在 10 个选项卡中运行相同的脚本,我清楚地看到一个在等待另一个,我清楚地看到 phpMyAdmin 通常只打开一个连接。
  • @jQguru,为什么会发生这种情况与连接无关。即使你有完全不同的连接,如果你有来自不同机器的并行脚本尝试对同一个表进行操作,那么表就会被锁定。根据正在执行的操作类型,表级或行级锁定会有所不同。这与新的或现有的连接无关..
  • 感谢您的解释。我已经在问题中发布了脚本的 MySQL 相关摘录。那里的东西可能会锁定桌子。
  • 如果您执行选择 *,则表将停止插入,直到选择完成。这是因为 MySQL 在 select 运行时无法更新。在设置事务时,您可以添加其他参数来控制锁定级别。检查我的答案中的更新
猜你喜欢
  • 2019-11-09
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 2016-10-15
  • 1970-01-01
相关资源
最近更新 更多