Doctrine2:找不到与findById同时存在的实体

时间:2012-10-05 22:16:58

标签: symfony doctrine-orm symfony-2.1

我有当前的设置:

常规Symfony2 Web请求可以创建并保留Job实体,该实体也会创建Gearman作业,我们可以在process 1中进行此操作。 Gearman Job由Gearman Worker执行,该工作人员通过Job实体的ID

我还使用Symfony创建一个Gearman Worker,它作为PHP CLI进程运行,让我们调用process 2

对于那些不熟悉Gearman的人来说,工人代码就是这样的:

for loop 5 times
    get job from gearman (blocking method call)
    get job entity from database
    do stuff

本质上,这段代码可以让一个Symfony2实例运行,以便在工作者死亡之前处理5个作业。

我的问题是:在工作人员处理的第一个作业Doctrine2能够使用以下代码从数据库中检索创建的作业而没有问题:

$job = $this->doctrine
            ->getRepository('AcmeJobBundle:Job')
            ->findOneById($job->workload()); // workload is the job id

但是,一旦此作业完成并且for循环递增以等待第二个作业,可以说这是来自process 3上的另一个Symfony2 Web请求,并Job创建ID 2 ,对Doctrine2存储库的调用返回null,即使该实体肯定在数据库中。

重新启动工作程序可以解决问题,因此当它执行第一个循环时,它可以选择Job 2。

有谁知道为什么会这样? getRepositoryfindOneById的第一次调用是否从MySQL执行某种表缓存,不允许它看到后来添加的Job 2?

只要数据库保持打开状态,MySQL是否只显示数据库到给定连接的快照?

我在尝试第二次调用entityManager之前尝试重置findOneBy无效。

感谢您提前获得任何建议,这一点真的让我感到难过。

更新

我创建了一个单独的进程测试用例,以排除它是否是导致问题的并发性,并且测试用例按预期执行。似乎存储库找不到作业2的唯一时间是将其添加到另一个进程的数据库中。

    // Job 1 already exists
    $job = $this->doctrine
    ->getRepository('AcmeJobBundle:Job')
    ->findOneById(1);

    $job->getId(); // this is fine.

    $em->persist(new Job()); // creates job 2

    $em->flush();

    $job = $this->doctrine
    ->getRepository('AcmeJobBundle:Job')
    ->findOneById(2);

    $job->getId(); // this is fine too, no exception.

1 个答案:

答案 0 :(得分:1)

也许一个进程在第二个进程保存之前尝试加载实体。

Doctrine通过id来缓存加载的实体,这样当你获得对同一个对象的第二个请求时,它会加载而不会对数据库进行另一个查询。您可以更多地了解Doctrine IdentityMap here