我有当前的设置:
一个常规的 Symfony2 Web 请求可以创建和持久化Job
实体,该实体也创建了一个Gearman作业,假设这发生在process 1
. Gearman Job 由一个 Gearman Worker 执行,它通过Job
实体的ID
.
我还使用 Symfony 创建了一个 Gearman Worker,它作为 PHP CLI 进程运行,我们称之为process 2
.
对于那些不熟悉 Gearman 的人来说,worker 代码的操作如下:
for loop 5 times
get job from gearman (blocking method call)
get job entity from database
do stuff
本质上,这段代码让一个 Symfony2 实例运行以在 worker 死亡之前处理 5 个 Job。
我的问题是:在工作人员处理 Doctrine2 的第一项工作中,使用以下代码可以毫无问题地从数据库中检索创建的工作:
$job = $this->doctrine
->getRepository('AcmeJobBundle:Job')
->findOneById($job->workload()); // workload is the job id
然而,一旦这个工作完成并且 for 循环递增以等待第二个工作,假设这是从另一个 Symfony2 Web 请求到达process 3
创建Job
with ID
2,即使实体肯定在数据库中,对 Doctrine2 存储库的调用也会返回 null .
重新启动工人解决了这个问题,所以当它执行它的第一个循环时,它可以拾取Job
2。
有谁知道为什么会这样?是否第一次调用getRepository
或findOneById
从 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.