首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Doctrine是使用Swoole关闭的

Doctrine是使用Swoole关闭的
EN

Stack Overflow用户
提问于 2019-07-19 09:10:34
回答 1查看 648关注 0票数 1

我有一个Laravel应用程序,它运行'swooletw/laravel-swoole‘来处理请求。Doctrine使用laravel-doctrine/orm作为对象关系映射。

通常,如果某个ORMException被抛出,它会关闭EntityManager,该the应该在下一次请求时自动打开/重置。但是,当我使用swoole时,它不会简单地发生,除非重新启动swoole worker,否则EntityManager将保持关闭状态。

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

代码语言:javascript
复制
    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 is Closed“。异常。

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

所以我把代码改成这样:

代码语言:javascript
复制
 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;
                });
            }
        }
    }

现在我把这个放在persist上:

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

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

EN

回答 1

Stack Overflow用户

发布于 2019-09-06 03:50:26

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

我发现,通过将Entity Manager包装到一个装饰器中,可以在需要时用新的实例替换实际的Entity Manager,而不是尝试在容器和所有可以注入它的服务中替换关闭的Entity Manager,而是使Entity Manager更容易重置:

代码语言:javascript
复制
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)();
    }
}

在每个请求的末尾,如果Entity Manager关闭,我会重新创建它,否则我只是将其清除以防止内存泄漏:

代码语言:javascript
复制
if ($this->entityManager->isOpen()) {
    $this->entityManager->clear();
} else {
    $this->entityManager->recreate();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57104356

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档