代码之家  ›  专栏  ›  技术社区  ›  Ole

PHP Gearman Worker功能与条令不同步

  •  1
  • Ole  · 技术社区  · 7 年前

    我观察到我的教义对象有一种奇怪的行为。在我的symfony项目中,我使用ORM和条令将数据保存在mysql数据库中。在大多数情况下,这是正常工作的。我还在我的项目中使用Gearman,这是一个允许应用程序并行完成任务的框架。我有一个 gearman job-server 在运行Apache的同一台机器上运行,并且在单独的“屏幕”会话中使用 screen 窗口管理器。通过这种方法,我总是可以从为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 回复  |  直到 7 年前
        1
  •  1
  •   Peter Belgrove    7 年前

    这就是我认为可能发生的事情。但可能是错误的。

    一个齿轮工将是一个长期运行的过程,它可以完成一些工作。它得到的第一个任务将导致条令从数据库将实体加载到其对象映射中。但是,对于工人接受的第二个任务,条令不会执行数据库查找,而是检查其标识映射,发现它已经加载了对象,因此只会从内存中返回该对象。如果工作进程外部的其他东西更改了数据库记录,那么您将得到一个过期的对象。

    您可以告诉条令从其标识映射中删除对象,然后它将执行数据库查找。若要再次强制从数据库加载对象,而不是从标识映射中提供这些对象,应使用EntityManager Clear()。

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

    推荐文章