【问题标题】:PHP gearman worker with shared DB connection具有共享数据库连接的 PHP gearman worker
【发布时间】:2023-03-31 03:48:01
【问题描述】:

我有一个用于从命令行(通过 supervisord)运行的 gearman 的 php worker,它充当一种“API”。 Worker 使用 mysqli 连接从数据库中检索数据并将其发送回连接的客户端。

class My_worker{
    private $worker;
    static $SQL;

public function __construct($SQL){

    $this->worker = new GearmanWorker();
    $this->worker->addServer();
    self::$SQL = $SQL;

//register workers
    $this->worker->addFunction("testA", array($this, 'testA') );
    $this->worker->addFunction("testB", array($this, 'testB') );
   }

public function run(){
    while ($this->worker->work()); 
}

static function testA(){ /* select field1 from DB; fetch row; return serialized; */}
static function testB(){ /* select field2 from DB; fetch row; return serialized; */}

}

//start worker
  $sql = new DB(SQL_HOST, SQL_USER, SQL_PWD, SQL_DB); //  Extends mysqli class
  $worker = new My_worker($sql);
  $worker->run();
}

所以,我有例如两个函数 'testA' 和 'testB' 从数据库中进行某些选择。问题是它们共享相同的数据库连接,因此如果同时对两个函数都有请求,则可能会从“错误”选择中获得结果,即 testB 从调用的选择中获取结果testA 而不是 testB

除了在每个函数中打开单独的数据库连接之外,有什么方法可以避免这种情况?

【问题讨论】:

    标签: php mysqli gearman


    【解决方案1】:

    恕我直言,查询总是并行处理,当前设置应该没有任何问题。 我可以想象这通过使用 PDO 和事务得到改善

    【讨论】:

    • 不,它们不是并行的,因为它们共享同一个对象来访问数据库,所以例如如果我在 testA 中调用 db->select(),我可以即使 5 分钟后仍然在 testB 中执行 db->fetch。当然,我可以尝试 db->result->free() ,但这并不能解决并行请求的问题。我想到的一个解决方案是调用 GearmanWorker::unregisterAll,这样在处理数据时就不能对这个 worker 进行其他调用。
    • 我想我找到了解决方案。我已经在每个函数中从 db select local 返回了结果。
    猜你喜欢
    • 2019-03-25
    • 2023-03-03
    • 2013-10-05
    • 1970-01-01
    • 2011-07-01
    • 2013-04-21
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多