symfony php WebSocket ratchet无法从条令中获取最新数据

waxmsbnn  于 2023-01-05  发布在  PHP
关注(0)|答案(3)|浏览(139)

相当有趣的事实,我刚刚发现,而搞乱了WebSocket应用程序,我现在使用Symfony 4.1和https://github.com/GeniusesOfSymfony/WebSocketBundle(这是建立在PHP棘轮)。
我想使用$repository->find(2);定期从MySQL数据库获取最新数据以进行测试,但它总是返回相同的结果,即使我在订阅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();
}

出于某种原因,这已经起作用了。有人能解释一下为什么find(2)方法没有得到最新的数据,而原始的SQL却得到了?

flvtvl50

flvtvl501#

这是正确的,也是ORM的预期行为。这是减轻数据库负载的一种方法。
这是有据可查的,但大多数时候我们只是跳到例子,错过了它。:)
由于PHP的生命周期,在应用程序中通常不会注意到这一点。一个请求进来,一个响应出去,然后一切都关闭了。下一个请求以一个干净的石板开始。
如果使用WebSocket,这种情况永远不会发生,PHP只是永远运行(不是真的,但理想情况下),棘轮响应事件。
(OFF:查看PHP-PM......他们之所以能够大幅增加每秒的请求,是因为他们颠覆了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

bnl4lu3b

bnl4lu3b2#

其实我自己也想明白了。
Doctrine的EntityManagerfind(...)方法实际上将结果缓存在一个实体的名称和条目ID下名为$unitOfWork的私有字段中。
每次尝试使用$em->find(...)查找内容并成功时,结果将存储在$this->unitOfWork中,如果再次尝试获取相同的内容,它将从缓存中加载。

// Check identity map first
    if (($entity = $unitOfWork->tryGetById($sortedId, $class->rootEntityName)) !== false) {
        if ( ! ($entity instanceof $class->name)) {
            return null;
        }

        switch (true) {
            case LockMode::OPTIMISTIC === $lockMode:
                $this->lock($entity, $lockMode, $lockVersion);
                break;

            case LockMode::NONE === $lockMode:
            case LockMode::PESSIMISTIC_READ === $lockMode:
            case LockMode::PESSIMISTIC_WRITE === $lockMode:
                $persister = $unitOfWork->getEntityPersister($class->name);
                $persister->refresh($sortedId, $entity, $lockMode);
                break;
        }

        return $entity; // Hit!
    }

"symfony/orm-pack": "^1.0""doctrine/orm": "^2.5.11"就是这种情况

    • 编辑:**

调用$repository->find(2, LockMode::NONE);可以解决这个问题。

mspsb9vt

mspsb9vt3#

我将php ratchet库与pimcore一起使用,并通过在套接字的"onOpen"事件上重新连接到数据库来修复此问题。
下面是代码:

public function onOpen(ConnectionInterface $conn)
{
    \Pimcore\Db::reset();
    $this->clients->attach($conn);
}

希望这个有用。

相关问题