【问题标题】:how to refresh doctrine connection multiple times during one script execution?如何在一个脚本执行期间多次刷新教义连接?
【发布时间】:2020-05-21 13:57:39
【问题描述】:


我需要非常频繁地执行 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 个此类命令同时运行时,它们不会 识别对方通过flush所做的更改。有没有办法 刷新连接,因此每次运行都会从中获取数据 数据库?
  2. 这个解决方案总体上真的很难看。我大概是 过度思考/过于复杂,所以请告知您是否看到任何 更好地实现我想要实现的目标。

现在我尝试在每个循环开始时使用EntityManager 的clear() 方法,但它没有改变任何东西。
我想过关闭连接,但后来我没有看到关闭后重新连接的任何简单方法。
感谢您的帮助。

【问题讨论】:

    标签: command-line doctrine-orm symfony4 cron-task


    【解决方案1】:

    现在我尝试在每个循环开始时使用 EntityManager 的 clear() 方法,但它没有改变任何东西。

    这正是您需要做的。清除 EntityManager 后,Doctrine 将发出数据库查询以获取新数据,因此您在其他命令/请求中所做的任何更改都将可供您使用。唯一不正确的情况是未关闭的交易,但我在您的代码中没有看到明确的交易,所以一切都应该没问题。

    【讨论】:

    • 谢谢,我不知道我之前搞砸了什么,它没有工作。由于其他一些不相关的问题,我一定已经放弃了这个想法。
    猜你喜欢
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 2012-09-16
    • 2020-07-29
    • 2018-12-14
    • 1970-01-01
    相关资源
    最近更新 更多