Я разрабатываю некоторые API на моем сервере, используя PHP. У меня есть скрипт, который делает запрос к базе данных и, после некоторой логики в результате запроса, он обновляет другую таблицу в базе данных, если это необходимо. Этот скрипт выполняется каждый раз, когда появляется новый запрос к определенному API.
Моя цель — установить логическое == true при запуске сценария и сбросить его до false при завершении сценария. Таким образом, все новые запросы могут читать логическое значение и запускать скрипт, только если boolean == false. В противном случае скрипт не будет выполнен из этого запроса, и это очень хорошо для моей цели.
Я знаю, что статические переменные в PHP сохраняют свое значение только в текущей области видимости, а переменные сеанса могут быть постоянными только в одном сеансе, но должен быть способ сделать это.
Моим первым решением было записать и обновить логическое значение в текстовом файле на сервере (или в базе данных) при запуске / завершении сценария и прочитать его перед запуском. Я не проверял это, но если есть много запросов, txt-файл (или строка базы данных) может обновляться асинхронно из большего количества запросов одновременно, поскольку в то время как один запрос устанавливает истинное логическое значение, другой запрос может уже прочитал это значение и снова запустил скрипт.
Возможно, вместо логического значения я сохраню дату или метку времени, поэтому с некоторой логикой скрипт будет выполняться только если
(last execution timestamp + 5 minutes) < now()
Есть ли решение для реализации этого?
Спасибо
Используйте стадо. В исключительном / неблокирующем состоянии вы можете выполнять код тогда и только тогда, когда ваш процесс имеет эксклюзивную блокировку.
$lock = fopen('/var/tmp/your.lock', 'a');
if (flock($lock, LOCK_EX|LOCK_NB)) {
// Do your read/update stuff
flock($lock, LOCK_UN); // Release the lock
}
Это позволит избежать состояния гонки и даст вам эксклюзивный доступ к чтению / записи нужных вам данных. Однако КАЖДЫЙ сценарий должен использовать один и тот же файл блокировки.
РЕДАКТИРОВАТЬ: Основываясь на комментарии ниже, я убедился, чтобы показать, что вам нужно снять блокировку.
Других решений пока нет …