douxiluan6555 2014-10-05 21:11
浏览 78

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?

  • 写回答

1条回答 默认 最新

  • duanliao3826 2014-10-06 19:57
    关注

    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.

    评论

报告相同问题?

悬赏问题

  • ¥15 Labview机器人问题
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序
  • ¥15 onvif+openssl,vs2022编译openssl64
  • ¥15 iOS 自定义输入法-第三方输入法
  • ¥15 很想要一个很好的答案或提示
  • ¥15 扫描项目中发现AndroidOS.Agent、Android/SmsThief.LI!tr