1

我有一个运行 'swooletw/laravel-swoole' 来处理请求的 Laravel 应用程序。Doctrine 被用作 ORM,使用laravel-doctrine/orm.

通常,如果学说抛出了一些 ORMException,它会关闭应该在下一次请求时自动打开/重置的 EntityManager。但是,当我使用 swoole 时,它​​不会简单地发生并且 EntityManager 保持关闭,除非重新启动 swoole 工作者。

我试图通过检查 entitmanager 是否已关闭并在中间件中将其重置来解决此问题。因此,在下一次请求时,它应该提供一个新的实体管理器。

    protected function handleClosedManagers()
    {
        foreach (Registry::getManagerNames() as $managerName) {
            /** @var EntityManager $manager */
            $manager = Registry::getManager($managerName);
            if (!$manager->isOpen()) {
                Registry::resetManager($managerName);
                $manager = Registry::getManager($managerName);
            }
        }
    }

理想情况下它应该修复它,但我得到“EntityManager 已关闭”。例外。

我假设我也需要从 laravel 容器中刷新它。

所以我将代码更改为:

 protected function handleClosedManagers()
    {
        foreach (Registry::getManagerNames() as $managerName) {
            /** @var EntityManager $manager */
            $manager = Registry::getManager($managerName);
            if (!$manager->isOpen()) {
                Registry::resetManager($managerName);
                $manager = Registry::getManager($managerName);
                app()->forgetInstance('doctrine.managers.'.$managerName);
                app()->forgetInstance('mem');
                app()->forgetInstance(MagentoEntityManager::class);
                app()->singleton('doctrine.managers.'.$managerName, function () use ($manager) {
                    return $manager;
                });
                // we are using separate entitymanager than default one
                app()->singleton('mem', function () use ($manager) {
                    return $manager;
                });
            }
        }
    }

现在我正在坚持这个:

ErrorException: Undefined index: 000000005ba55063000000001b2f101d in file /***/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 3003

有人知道处理这种情况的正确方法吗?

4

1 回答 1

0

我在 Zend Expressive 应用程序中遇到了同样的问题。

与其尝试替换容器中的封闭实体管理器和可能已经注入它的所有服务,我发现通过将实体管理器包装到装饰器中来使其可重置更容易,这允许用新实例替换实际的实体管理器。需要:

final class ResettableEntityManager extends \Doctrine\ORM\Decorator\EntityManagerDecorator
{
    /**
     * @var callable
     */
    private $entityManagerFactory;

    public function __construct(callable $entityManagerFactory)
    {
        $this->entityManagerFactory = $entityManagerFactory;
        parent::__construct($entityManagerFactory());
    }

    public function recreate(): void
    {
        $this->wrapped = ($this->entityManagerFactory)();
    }
}

在每个请求结束时,如果它已关闭,我会重新创建实体管理器,否则我只是将其清除以防止内存泄漏:

if ($this->entityManager->isOpen()) {
    $this->entityManager->clear();
} else {
    $this->entityManager->recreate();
}
于 2019-09-05T19:50:25.560 回答