Doctrine2 и MongoDB — фактическое значение не извлекается из базы данных в длинном цикле опроса

Мы реализуем длинный опрос в нашем приложении Symfony, поэтому controller1 обновляет некоторый член экземпляра класса User

     $dm = $this->get('doctrine_mongodb')->getManager();
...
$User->setSomeValue($value);
$dm->persist($User);
$dm->flush();

Другой контроллер2, который содержит длинный цикл опроса первым
извлекает $ user и значение из базы данных, затем с некоторым интервалом
выполняет $ dm-> refresh ($ User) и извлекает значение.

     $dm = $this->get('doctrine_mongodb')->getManager();
...
$User=$userRepo->findOneBy(array('id' => $userId));
$value = $User->getSomeValue();
...
while(...){
sleep(1);
$iteration++;
$dm->refresh($User);
$value = $User->getSomeValue();
...
}

Если controller1 обновляет значение во время выполнения цикла, старое значение выбирается контроллером 2 внутри цикла, но не обновляется.

В чем проблема?

0

Решение

Я не могу воспроизвести проблему, которую вы описываете, с помощью следующих сценариев CLI. Они смоделированы после tools/sandbox/index.php пример (включен в репозиторий ODM) и выполняются из того же каталога.

Первый сценарий, poll.php, обновляет конкретный документ раз в секунду и печатает строковое поле:

<?php

require_once __DIR__ . '/config.php';

$id = new MongoId('5432e4e6e84df199228b4567');
$repo = $dm->getRepository('Documents\User');
$user = $repo->findOneBy(['_id' => $id]);
$iteration = 0;
printf("%d: %s\n", $iteration, $user->getUsername());

poll: {
sleep(1);
$iteration++;
$dm->refresh($user);
printf("%d: %s\n", $iteration, $user->getUsername());
}

goto poll;

Второй сценарий, modify.php, изменяет поле того же документа на случайную строку.

<?php

require_once __DIR__ . '/config.php';

use Documents\User;

$id = new MongoId('5432e4e6e84df199228b4567');
$user = new User();
$user->setId($id);
$user->setUsername(md5(rand()));

$dm->persist($user);
$dm->flush();

printf("Changed username to: %s\n", $user->getUsername());

Я сделал одно небольшое изменение в tools/sandbox/Documents/User.php модель и добавил setId() метод. Это позволяет modify.php скрипт для выполнения upsert при первом запуске и создания документа, который мы позже изменим.

С этими двумя файлами я начал с создания документа:

$ php modify.php
Changed username to: 9bdfab05b06306e97d2f63c9bc0a34ef

Я тогда начал poll.php во втором терминале и приступил к запуску modify.php несколько раз:

$ php poll.php
0: 9bdfab05b06306e97d2f63c9bc0a34ef
1: 9bdfab05b06306e97d2f63c9bc0a34ef
2: 8420c8ef0ee7194624fead56585e8be5
3: 8420c8ef0ee7194624fead56585e8be5
4: bf2ec4bafae4cf47e3162ce857e861e7
5: bf2ec4bafae4cf47e3162ce857e861e7
6: bf2ec4bafae4cf47e3162ce857e861e7
7: 2051dd54bc2883f6c11e6c2bbfdfd13e
8: 2051dd54bc2883f6c11e6c2bbfdfd13e
9: 2051dd54bc2883f6c11e6c2bbfdfd13e

Если вы отслеживаете звонки внутри DocumentManager::refresh()вы увидите, что это в конечном итоге вызывает DocumentPersister::refresh(), который очень просто запрашивает необработанные данные документа через Doctrine\MongoDB\Collection класс-обертка, гидратирует эти данные и сбрасывает исходные данные документа (используется для вычисления набора изменений). Отладка необработанных данных (из MongoDB), которые гидратируются и переназначаются для моментального снимка, было бы хорошим началом, если вы не видите новые данные.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]