php gearman worker 函数不与学说同步

php gearman worker function no synchronized with doctrine

我观察到我的学说对象有一个奇怪的行为。在我的 symfony 项目中,我使用 ORM 和 doctrine 将我的数据保存在 mysql 数据库中。这在大多数情况下都是正常的。我也在我的项目中使用了gearman,这是一个允许应用程序并行完成任务的框架。我有一位 gearman job-server running on the same machine where also my apache is running and I have registered a gearman worker on the same machine in a seperate 'screen' session using the screen window 经理。通过这种方法,我总是可以通过为 gearman-worker 注册的功能访问标准控制台。

在我调用的 gearman-worker 函数中,我可以通过 $doctrine = $this->getContainer()->get('doctrine') 访问 doctrine 对象,它几乎可以正常工作。但是当我更改了数据库中的一些数据时,学说仍在使用以前存储在数据库中的旧数据。我完全糊涂了,因为我预计通过调用:

$repo = $doctrine->getRepository("PackageManagerBundle:myRepo"); $dbElement = $repo->findOneById($Id);

我总是从我的数据库中获取当前数据条目。这看起来像是一种奇怪的缓存行为,但我不知道我做错了什么。

我可以通过注册 gearman worker 和新功能来解决这个问题:

$worker = new \GearmanWorker(); $worker->addServer(); $worker->addFunction

之后,我恢复了数据库的当前状态,直到我更改了其他内容。我只在我的 gearman worker 函数中观察到这种行为。在应用程序的其余部分,一切都与我的数据库同步并且正常。

这就是我认为可能发生的情况。虽然可能是错误的。

gearman worker 将是一个漫长的 运行 过程来挑选工作要做。它获得的第一份工作将导致 doctrine 将实体从数据库加载到其对象映射中。但是,对于 worker 收到的第二份工作,doctrine 不会执行数据库查找,而是会检查它的身份映射并发现它已经加载了对象,因此只会 return 内存中的那个。如果工作进程外部的其他东西改变了数据库记录,那么您最终会得到一个过时的对象。

你可以告诉 doctrine 从它的身份映射中删除对象,然后它会执行数据库查找。要再次强制从数据库加载对象而不是从身份映射提供对象,您应该使用 EntityManager#clear()。

更多信息在这里: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html#entities-and-the-identity-map