Как проверить в Doctrine что строка всё ещё есть в наличии в таблице БД?

Я не совсем новичок в Doctrine, в частности, я более-менее знаю, как использовать методы refresh() и flush(). Однако, как я сейчас проверил в ходе эксперимента, refresh() не упадёт с ошибкой, если строка, соответствующая загруженной Entity, была удалена (например, напрямую в БД администратором или другим скриптом).

Я понимаю, что это сделано не просто так, и на то есть причины. Однако это приводит меня к следующему вопросу.

В системе существует длительный процесс (их может исполняться несколько параллельно), запускающийся через php-cli и работающий примерно 12-15 минут. В начале него создаётся три разных entity и делается flush. В первой таблице хранится основной набор данных, по ходу процесса в другой связанной таблице обновляется специальное поле со статусом процесса. В третьей таблице создаётся строка, куда потом будут записаны результаты операции. Соответственно, на каждый активный процесс существует по одной строке в каждой из трёх таблиц (для завершённых ранее процессов все эти строки тоже существуют, в этих связках статус во второй таблице равен "Finished").

Я подумал, что возможно, было бы реальным решением убивать процесс не через sudo kill {PID} (PID известен и хранится в БД в одной из таблиц), добавляя пользователя www-data в список sudoers на сервере, а просто удаляя строчку в базе данных (во всех трёх таблицах, так как там равные Primary Key) через интерфейс админа системы, а в цикле внутри длительного скрипта проверяя, не была ли удалена данная строка. Однако refresh() "не видит" удаления строки из БД.

Как я должен поступить в таком случае? Предпочтительнее ли использовать sudo kill, или я должен создать дополнительную колонку в таблице, назвать её is_stopped и после вызова resresh() проверять уже её значение?


Ответы (1 шт):

Автор решения: Borislav

Вы реализуете IPC, т.е. некое межпроцессорное взаимодействие, об этом написано множество книг (это на всякий).

В вашем конкретном случае, стоит отдать предпочтение long pool-у, т.е. в базе колонка is_stopped (stopedAt) выглядит предпочтительней. Т.к. поведение будет максимально контролируемым, так же как бонус, будете фиксировать время остановки и выходить из скрипта самим кодом, а не стрелять его (через kill у вас в теории может возникнуть неконсистентное состояние, если не используете транзакций или используете хранилище, которое не поддерживает ACID).

Так же можно попробовать реализовать graceful shutdown через прослушку сигналов OS, однако, вам нужна Symfony 6.3+. Описано тут: https://jolicode.com/blog/handling-signal-with-symfony-command

→ Ссылка