我观察到我的目标有一种奇怪的行为。在我的symfony项目中,我使用orm和条令将数据保存在mysql数据库中。这在大多数情况下是正常的。我也在我的项目中使用gearman,这是一个允许应用程序并行完成任务的框架。我有一个gearman作业服务器在同一台机器上运行,我的apache也在运行,我已经在同一台机器上注册了一个gearman worker,使用屏幕窗口管理器在一个单独的“屏幕”会话中。通过这种方法,我始终可以访问gearman worker注册函数之外的标准控制台。
在我调用的gearman worker函数中,我可以通过 $doctrine = $this->getContainer()->get('doctrine')
它几乎正常工作。但当我更改了数据库中的一些数据时,条令仍然使用以前存储在数据库中的旧数据。我完全糊涂了,因为我以为打电话时: $repo = $doctrine->getRepository("PackageManagerBundle:myRepo"); $dbElement = $repo->findOneById($Id);
我总是从数据库中获取当前的数据条目。这看起来像是一个奇怪的缓存行为,但我不知道我做错了什么。
我可以通过注册gearman worker和函数new来解决这个问题: $worker = new \GearmanWorker(); $worker->addServer(); $worker->addFunction
在此之后,我将返回数据库的当前状态,直到我更改了其他内容。我只在gearman worker函数中观察这种行为。在应用程序的其余部分,所有事情都与我的数据库和普通数据库同步。
1条答案
按热度按时间jpfvwuh41#
这就是我认为可能发生的事情。可能是错的。
gearman工人将是一个长期运行的过程,负责挑选工作。然后,它得到的第一个作业将导致条令将实体从数据库加载到其对象Map中。但是,对于worker接收的第二个作业,document将不执行数据库查找,而是检查它的标识Map,发现它已经加载了对象,因此将简单地从内存中返回该对象。如果工作进程外部的其他东西更改了数据库记录,那么您将得到一个过期的对象。
您可以告诉条令从其标识Map中删除对象,然后它将执行数据库查找。要强制再次从数据库加载对象,而不是从标识Map提供对象,应使用entitymanager#clear()。
更多信息请点击此处:https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html#entities-还有身份Map