php websocket棘轮不';t从条令中获取最新数据
我在搞砸WebSocket应用程序时发现了一个非常有趣的事实,我现在正在使用Symfony 4.1和(它是基于PHP Ratchet构建的)构建WebSocket应用程序 我想使用php websocket棘轮不';t从条令中获取最新数据,php,symfony,websocket,doctrine,ratchet,Php,Symfony,Websocket,Doctrine,Ratchet,我在搞砸WebSocket应用程序时发现了一个非常有趣的事实,我现在正在使用Symfony 4.1和(它是基于PHP Ratchet构建的)构建WebSocket应用程序 我想使用$repository->find(2)定期从MySQL数据库中获取最新的数据,以便进行测试但它总是返回相同的结果,即使我在订阅WebSocket频道时更改了数据 在花了好几个小时弄乱代码和哭泣之后,我发现出于某种原因,条令正在缓存结果(或者我认为它就是这样做的) 为了验证我的理论,我创建了一个服务,该服务使用以下代码
$repository->find(2)定期从MySQL数据库中获取最新的数据,以便进行测试
但它总是返回相同的结果,即使我在订阅WebSocket频道时更改了数据
在花了好几个小时弄乱代码和哭泣之后,我发现出于某种原因,条令正在缓存结果(或者我认为它就是这样做的)
为了验证我的理论,我创建了一个服务,该服务使用以下代码处理从数据库中获取的数据:
/**
* @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却产生了最新的数据吗?事实上,我自己也设法解决了这个问题
Doctrine的EntityManagerfind(…)
方法实际上将结果缓存在名为$unitOfWork
的私有字段中实体名称和条目ID下
每次您尝试使用$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包”:“^1.0”
和“条令/orm”:“^2.5.11”
编辑:
调用
$repository->find(2,LockMode::NONE)代码>解决了这个问题 事实上,我自己也设法解决了这个问题
Doctrine的EntityManagerfind(…)
方法实际上将结果缓存在名为$unitOfWork
的私有字段中实体名称和条目ID下
每次您尝试使用$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包”:“^1.0”
和“条令/orm”:“^2.5.11”
编辑:
调用$repository->find(2,LockMode::NONE)代码>解决了这个问题 这是正确的,是ORM的预期行为。这是减轻数据库负载的一种方法
它有很好的文档记录,但大多数情况下我们只是跳过示例,错过了它。:)
由于PHP的生命周期,您通常不会在应用程序中注意到这一点。一个请求进来,一个响应出去,然后一切都关闭了。下一个请求从一个干净的板岩开始
如果您使用websocket,这种情况永远不会发生,PHP只是永远运行(不是真的,但理想情况下),ratchet会响应事件
(关闭:查看PHP-PM…他们能够实现请求/秒的急剧增加,因为他们破坏了PHP生命周期)
锁定模式是一种解决方案,但您也可以调用$em->refresh($entity)
,这会触发从数据库重新加载
编辑:docs这是正确的,是ORM的预期行为。这是减轻数据库负载的一种方法
它有很好的文档记录,但大多数情况下我们只是跳过示例,错过了它。:)
由于PHP的生命周期,您通常不会在应用程序中注意到这一点。一个请求进来,一个响应出去,然后一切都关闭了。下一个请求从一个干净的板岩开始
如果您使用websocket,这种情况永远不会发生,PHP只是永远运行(不是真的,但理想情况下),ratchet会响应事件
(关闭:查看PHP-PM…他们能够实现请求/秒的急剧增加,因为他们破坏了PHP生命周期)
锁定模式是一种解决方案,但您也可以调用$em->refresh($entity)
,这会触发从数据库重新加载
编辑:docs是的,很有趣,我在处理那些小型HTTP请求时错过了这种行为,哈哈。谢谢!我不确定,但我想我是在兔子身上首先注意到的。在一个简单的应用程序中很容易出错。:)是的,很有趣,我在处理那些小HTTP请求时错过了这个行为,哈哈。谢谢!我不确定,但我想我是在兔子身上首先注意到的。在一个简单的应用程序中很容易出错。:)