如何禁用Laravel DB重新连接?

m1m5dgzv  于 2023-03-04  发布在  其他
关注(0)|答案(1)|浏览(141)

我们的分析系统,工作与巨大的数据库。一些查询可能需要几个小时。我们创建数据库查询,60秒后,如果它没有完成,我们杀死它,并添加此查询作为作业到队列。
现在,我们将系统迁移到Laravel,在这里,我们遇到了删除查询的问题。在删除数据库中的查询后,它会创建另一个查询,只有在第二次删除后,它才会发出异常MySQL服务器已离开
我调查了Laravel堆栈,发现了一个函数,它发生供应商/laravel/框架/src/Illuminate/数据库/连接.php

protected function handleQueryException(QueryException $e, $query, $bindings, Closure $callback)
    {
        if ($this->transactions >= 1) {
            throw $e;
        }

        return $this->tryAgainIfCausedByLostConnection(
            $e, $query, $bindings, $callback
        );
    }

protected function tryAgainIfCausedByLostConnection(QueryException $e, $query, $bindings, Closure $callback)
    {
        if ($this->causedByLostConnection($e->getPrevious())) {
            $this->reconnect();

            return $this->runQueryCallback($query, $bindings, $callback);
        }

        throw $e;
    }

没有任何参数可以避免它,只有使用事务,但它是选择查询,没有意义。
你知道我们如何从第一次尝试中获得异常吗?
通常我们保存连接ID:

session(['process_id' => DB::selectOne('SELECT CONNECTION_ID() AS id')->id]);
session()->save();

然后用一句话把它干掉:

DB::statement("KILL $id");

但后来我们有了另一个连接,需要再次杀死它。

mwkjh3gx

mwkjh3gx1#

我在AppServiceProvider中添加了连接覆盖:

/**
 * Replace method to avoid reconnect after killing query
 * @return void
 */
private function overrideConnection(): void
{
    \Illuminate\Database\Connection::resolverFor('mysql', static function ($pdo, $database, $tablePrefix, $config) {
        return new \App\Overrides\Connection($pdo, $database, $tablePrefix, $config);
    });
}

并创建了检查配置选项并避免重新连接的新Connection类:

class Connection extends MySqlConnection
{
    /**
     * Handle a query exception.
     *
     * @param  QueryException  $e
     * @param  string  $query
     * @param  array  $bindings
     * @param  \Closure  $callback
     * @return mixed
     *
     * @throws QueryException
     */
    protected function handleQueryException(QueryException $e, $query, $bindings, \Closure $callback)
    {
        if ($this->transactions >= 1 || false === $this->getConfig('reconnect')) {
            throw $e;
        }

        return $this->tryAgainIfCausedByLostConnection(
            $e, $query, $bindings, $callback
        );
    }
}

相关问题