Symfony Doctrine EntityManager 没有正确刷新
Symfony Doctrine EntityManager not refreshing properly
我有一个棘轮 WebSocket 服务器,其 entityManager
是从后端初始化的。但是,如果由于 WebSocket 服务器 entityManager
的状态与后端不同,其中一个前端发生了某些更改,则新更改不会反映在 WebSocket 服务器提供的数据中。
为此,我在后端编写了一些侦听器,用于侦听这些实体中的更改,然后向服务器发送请求,如下所示:
public function postUpdate(Room $entity, LifecycleEventArgs $_)
{
try {
Loop::run(function() use ($entityName, $id) {
$conn = yield connect('ws://localhost:8080');
yield $conn->send(json_encode(['message' => $entityName, 'data' => ['duid' => $id]]));
$conn->close();});
} catch (Exception $e) {}
}
然后我在 WebSocket 服务器中获取实体并简单地刷新它,如下所示:
function onMessage(ConnectionInterface $from, $msg)
{
try {
$messageData = json_decode($msg);
switch ($messageData->message) {
case BookingSocketActions::ROOM_CHANGED_EVENT:
// $room = $this->entityManager->getRepository('ResourcesBundle:Room')
// ->find(['id' => $id]);
$room = $this->entityManager->getRepository('ResourcesBundle:Room')
->findRoomDetailById($messageData->data->duid);
// $this->entityManager->clear();
$this->entityManager->refresh($room);
break;
}
} catch (Exception $ex) {
$from->send($ex);
}
}
现在出现了一个奇怪的错误:在 WebSocket 服务器中刷新的 $entity
状态总是落后于实体的真实变化。假设我将 $entity->name
从“1”更改为“2”。
刷新后 $entity->name
在 WebSocket 服务器上仍然是“1”。只有当我再次将其更改为其他内容时,例如“3”,会不会变成“2”(刷新后)。如果我把它改成“4”,它就会变成“3”等等。
事件正在从后端正确触发,实体正在服务器上正确获取。只是 refresh()
仅适用于对 WebSocket 服务器的第二次请求(因此是第二次刷新),而不适用于第一次请求。
我什至尝试过 $entityManager->merge($entity);
但没有结果。
我正在使用 symfony 3.4、doctrine 2.7 和 ratchet 0.4.3。
Doctrine 使用 identity map
websocket 服务器是一个 守护进程,所有清理任务均由开发人员负责
使用
\Doctrine\ORM\EntityManager::find
与 $lockMode
参数 = \Doctrine\DBAL\LockMode::NONE
或
在\Doctrine\ORM\EntityManager::find
之前调用\Doctrine\ORM\EntityManager::clean
方法
首先可能是触发检测更新变化的事件
如果您 postPersist
数据库中的实体不会发生变化。它会在 flush
发生之前触发。
您需要在 flush
.
之后触发消息到套接字服务器
第二件事是确保 entityManager 实例分离并重新加载 room
实体实例。这可以用
来完成
$this->entityManager->getUnitOfWork()->clear(Room::class);
就在您再次查询实体之前
$this->entityManager->getUnitOfWork()->clear(Room::class);
$room = $this->entityManager
->getRepository('ResourcesBundle:Room')
->findRoomDetailById($messageData->data->duid);
我有一个棘轮 WebSocket 服务器,其 entityManager
是从后端初始化的。但是,如果由于 WebSocket 服务器 entityManager
的状态与后端不同,其中一个前端发生了某些更改,则新更改不会反映在 WebSocket 服务器提供的数据中。
为此,我在后端编写了一些侦听器,用于侦听这些实体中的更改,然后向服务器发送请求,如下所示:
public function postUpdate(Room $entity, LifecycleEventArgs $_)
{
try {
Loop::run(function() use ($entityName, $id) {
$conn = yield connect('ws://localhost:8080');
yield $conn->send(json_encode(['message' => $entityName, 'data' => ['duid' => $id]]));
$conn->close();});
} catch (Exception $e) {}
}
然后我在 WebSocket 服务器中获取实体并简单地刷新它,如下所示:
function onMessage(ConnectionInterface $from, $msg)
{
try {
$messageData = json_decode($msg);
switch ($messageData->message) {
case BookingSocketActions::ROOM_CHANGED_EVENT:
// $room = $this->entityManager->getRepository('ResourcesBundle:Room')
// ->find(['id' => $id]);
$room = $this->entityManager->getRepository('ResourcesBundle:Room')
->findRoomDetailById($messageData->data->duid);
// $this->entityManager->clear();
$this->entityManager->refresh($room);
break;
}
} catch (Exception $ex) {
$from->send($ex);
}
}
现在出现了一个奇怪的错误:在 WebSocket 服务器中刷新的 $entity
状态总是落后于实体的真实变化。假设我将 $entity->name
从“1”更改为“2”。
刷新后 $entity->name
在 WebSocket 服务器上仍然是“1”。只有当我再次将其更改为其他内容时,例如“3”,会不会变成“2”(刷新后)。如果我把它改成“4”,它就会变成“3”等等。
事件正在从后端正确触发,实体正在服务器上正确获取。只是 refresh()
仅适用于对 WebSocket 服务器的第二次请求(因此是第二次刷新),而不适用于第一次请求。
我什至尝试过 $entityManager->merge($entity);
但没有结果。
我正在使用 symfony 3.4、doctrine 2.7 和 ratchet 0.4.3。
Doctrine 使用 identity map
websocket 服务器是一个 守护进程,所有清理任务均由开发人员负责
使用
\Doctrine\ORM\EntityManager::find
与 $lockMode
参数 = \Doctrine\DBAL\LockMode::NONE
或
在\Doctrine\ORM\EntityManager::find
\Doctrine\ORM\EntityManager::clean
方法
首先可能是触发检测更新变化的事件
如果您 postPersist
数据库中的实体不会发生变化。它会在 flush
发生之前触发。
您需要在 flush
.
第二件事是确保 entityManager 实例分离并重新加载 room
实体实例。这可以用
$this->entityManager->getUnitOfWork()->clear(Room::class);
就在您再次查询实体之前
$this->entityManager->getUnitOfWork()->clear(Room::class);
$room = $this->entityManager
->getRepository('ResourcesBundle:Room')
->findRoomDetailById($messageData->data->duid);