我对 Doctrine 并不是完全陌生,特别是我或多或少知道如何使用refresh()和flush()。但是,正如我现在在实验过程中检查的那样,refresh()如果删除了与加载的实体对应的行(例如,由管理员或其他脚本直接在数据库中删除),则不会因错误而失败。
我知道这样做是有原因的,而且这是有原因的。然而,这引出了我的下一个问题。
系统中有一个很长的进程(它们可以并行执行多个),通过 php-cli 启动并运行大约 12-15 分钟。在开始时,创建了三个不同的实体并完成了刷新。第一个表存储主要数据集;随着流程的进展,另一个相关表中会更新包含流程状态的特殊字段。在第三个表中创建一行,稍后将写入操作结果。因此,对于每个活动流程,三个表中的每一个都有一行(对于先前完成的流程,所有这些行也存在,在这些链接中,第二个表中的状态为“已完成”)。
sudo kill {PID}我认为这也许是一个真正的解决方案,不是通过将 www-data 用户添加到服务器上的 sudoers 列表(PID 已知并存储在数据库中的一个表中)来终止进程,而是简单地通过通过系统管理界面删除数据库中的行(在所有三个表中,因为它们等于主键),并在长脚本内循环检查该行是否已被删除。但是,它refresh()“看不到”从数据库中删除的行。
这种情况我该怎么办?最好使用sudo kill,还是应该在表中创建一个附加列,为其命名is_stopped并resresh()在调用后检查其值?
您实现 IPC,即某种处理器间交互,很多书都写过这方面的内容(仅供所有人参考)。
在您的具体情况下,您应该优先考虑长池,即在数据库中, is_stopped (stopedAt) 列看起来更可取。因为行为将尽可能受到控制,还有一个好处,您将记录停止时间并使用代码本身退出脚本,而不是触发它(使用kill,理论上,如果您这样做,您可能会出现不一致的状态不使用事务或使用不支持ACID的存储)。
您还可以尝试通过监听操作系统信号来实现正常关闭,但是,您需要 Symfony 6.3+。此处描述:https://jolicode.com/blog/handling-signal-with-symfony-command