php websocket棘轮不从学说中获取最新数据

Mil*_*ach 1 php doctrine websocket symfony ratchet

我刚刚在使用 Symfony 4.1 和https://github.com/GeniusesOfSymfony/WebSocketBundle(它建立在 PHP Ratchet 上)构建的WebSocket 应用程序中发现了一个非常有趣的事实。

我想定期从 MySQL 数据库中获取最新数据用于测试目的,$repository->find(2);但它总是返回相同的结果,即使我在订阅 WebSocket 通道时更改数据。

经过相当多的时间弄乱代码并哭泣之后,我发现由于某种原因,Doctrine 正在缓存结果(或者我认为它就是这样做的)。

为了测试我的理论,我创建了一个服务,使用以下代码处理从数据库中获取数据:

/**
 * @return mixed
 * @throws \Doctrine\DBAL\DBALException
 */
public function fetchNewest()
{
    $stmt = $this->em->getConnection()->prepare('SELECT * FROM test WHERE id=2');
    $stmt->execute();

    return $stmt->fetch();
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,这奏效了。谁能解释为什么find(2)方法没有产生最新的数据,而原始 SQL 却产生了?

Pad*_*m87 5

这是正确的,也是 ORM 的预期行为。这是减轻数据库负载的一种方法。

它有据可查,但大多数时候我们只是跳到示例中而错过了它。:)

由于 PHP 生命周期的原因,您通常不会在应用程序中注意到这一点。一个请求进来,一个响应出去,一切都关闭了。下一个请求从一个干净的石板开始。

如果你使用 websocket,这永远不会发生,PHP 只是永远运行(不是真的,但理想情况下),棘轮响应事件。

(关闭:查看 PHP-PM...他们已经能够达到 request/s 的急剧增加,因为他们颠覆了 PHP 生命周期)。

锁定模式是一种解决方案,但您也可以调用$em->refresh($entity),它会触发从 db 重新加载。

编辑:文档https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html#entities-and-the-identity-map