Doctrine2和MongoDB - 在长轮询循环中不从数据库中获取实际值

We are implementing the long-polling in our Symfony application, so the controller1 updates some member of the instance of the class User

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

Another controller2 which contains long-polling loop first fetches the $user and value from database then with some interval does $dm->refresh($User) and pulls the value.

     $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();
...
     }

If controller1 updates the value during the loop execution the old value is fetched by controller2 inside the loop but not an updated one.

What is the issue?

I can't reproduce the issue you're describing with the following CLI scripts. These are modeled after the tools/sandbox/index.php example (included in the ODM repository) and are being run from the same directory.

The first script, poll.php, refreshes a particular document once a second and prints some string field:

<?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
", $iteration, $user->getUsername());

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

goto poll;

The second script, modify.php, changes the same document's field to a random string.

<?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
", $user->getUsername());

I made one small change to the tools/sandbox/Documents/User.php model and added a setId() method. This allows the modify.php script to do an upsert on the first run and create the document we'll later modify.

With these two files in place, I started things off by creating the document:

$ php modify.php 
Changed username to: 9bdfab05b06306e97d2f63c9bc0a34ef

I then started poll.php in a second terminal and proceeded to run modify.php a few times:

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

If you trace the calls within DocumentManager::refresh(), you'll see that it ultimately calls DocumentPersister::refresh(), which very simply queries for the raw document data via the Doctrine\MongoDB\Collection wrapper class, hydrates that data, and resets the original document data (used for changeset computation). Debugging the raw data (from MongoDB) that gets hydrated and re-assigned to the snapshot would be a good place to start if you're not seeing the new data.