如何在一个脚本执行过程中多次刷新doctrine连接?

问题描述 投票:-1回答:1

我需要频繁地执行Symfony命令(比如每5-10秒),但是我的运行环境限制了cron触发的最低时间为1分钟。所以,我想出了一个非常讨厌的解决方案,看起来像这样。我已经创建了 AbstractRepetitiveCommand 类,然后我对其进行了扩展,提供了对 workToExecute 的方法。

abstract class AbstractRepetitiveCommand extends Command
{
    protected int $overallMinutes = 1;

    protected int $timesPerMinute = 60;


    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $startTime = microtime(true);

        while (microtime(true) < $startTime + 60 * $this->overallMinutes - 60 / $this->timesPerMinute) {
            if (isset($last) && microtime(true) < $last + 60 / $this->timesPerMinute) {
                continue;
            }
            $last = microtime(true);
            $this->workToExecute($input, $output);
        }
    }


    protected function workToExecute(InputInterface $input, OutputInterface $output)
    {
        return;
    }
}

class DoChecksCommand extends AbstractRepetitiveCommand
{
    protected int $overallMinutes = 5;
    protected int $timePerMinute = 4;
    protected static $defaultName = 'checks:do';
    /**
     * @var InvestmentCheckerService
     */
    private InvestmentCheckerService $checkerService;
    /**
     * @var EntityManagerInterface
     */
    private EntityManagerInterface $entityManager;


    public function __construct(InvestmentCheckerService $checkerService, EntityManagerInterface $entityManager)
    {
        parent::__construct('DoChecks');
        $this->checkerService = $checkerService;
        $this->entityManager = $entityManager;
    }


    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @throws \Exception
     */
    protected function workToExecute(InputInterface $input, OutputInterface $output)
    {
        /** @var ArrayCollection | Pair[] $pairs */
        $pairs = $this->entityManager->getRepository(Pair::class)->findAll();
        foreach ($pairs as $pair) {
            $this->checkerService->processChecks($pair);
            $this->entityManager->persist($pair);
            $this->entityManager->flush();
        }
    }
}

这种方法有两个问题。

  1. 当2个这样的命令同时运行时 它们不能识别对方通过刷新所做的改变。有没有一种方法可以刷新连接,使每次运行都能从数据库中获取数据?
  2. 这个方案总体来说很丑陋。可能是我想的太复杂了,所以请大家建议是否有更好的方法来达到我想要的目标。

目前我已经尝试使用 clear() 方式 EntityManager 在每个循环的开始,但它没有任何改变。 我想过关闭连接,但又看不到关闭后有什么简单的方法可以重新连接。 谢谢你的帮助。

command-line doctrine-orm symfony4 cron-task
1个回答
1
投票

目前,我已经尝试在每个循环的开始使用EntityManager的clear()方法,但它没有任何改变。

这正是你需要做的。当EntityManager被清空后,Doctrine会发出数据库查询来获取新的数据,所以你在其他命令请求中所做的任何改变都会对你有用。唯一不会是真的情况是未关闭的事务,但我看到你的代码中没有明确的事务,所以一切都应该是好的。

© www.soinside.com 2019 - 2024. All rights reserved.