Мне нужно использовать мьютексы или семафоры в PHP, и это пугает меня. Чтобы уточнить, я не боюсь писать беззаконный код, который правильно синхронизируется или боится опасностей параллельного программирования, но о том, насколько хорошо PHP обрабатывает случаи, связанные с ошибками.
Краткая справочная информация: создание интерфейса обработчика кредитных карт, который находится между пользователями и сторонним шлюзом кредитных карт. Необходимо предотвратить дублирование запросов и уже иметь систему, которая работает, но если пользователь попадает в submit (без участия JS, поэтому я не могу отключить кнопку для них) в миллисекундах, возникает условие гонки, где мой PHP script не понимает, что был сделан двойной запрос. Вам нужен семафор/мьютекс, поэтому я могу обеспечить только один успешный запрос для каждой уникальной транзакции.
Я запускаю PHP за nginx через PHP-FPM с несколькими процессами на многоядерной машине Linux. Я хочу быть уверенным, что
- семафоры разделяются между всеми процессами php-fpm и всеми ядрами (ядро i686).
- php-fpm обрабатывает сбой PHP-процесса, сохраняя мьютекс/семафор и освобождая его соответственно.
- php-fpm обрабатывает прерывание сеанса при сохранении мьютекса/семафора и соответственно освобождает его.
Да, я знаю. Очень простые вопросы, и было бы глупо думать, что подходящего решения не существует для какого-либо другого программного обеспечения. Но это PHP, и это, безусловно, не было построено с учетом concurrency, оно часто сбой (в зависимости от того, какие расширения вы загрузили) и находится в изменчивой среде (PHP-FPM и в Интернете).
Что касается (1), я предполагаю, что PHP использует функции POSIX, которые оба эти условия сохраняются на машине SMP i686. Что касается (2), я вижу, что вкратце просматриваю документы, что есть параметр, который решает это поведение (хотя почему бы вы никогда не захотели, чтобы PHP НЕ выпускал мьютекс, сеанс убит, я не понимаю). Но (3) является моей главной заботой, и я не знаю, можно ли предположить, что php-fpm правильно обрабатывает все случаи. Я (очевидно) никогда не хочу тупика, но я не уверен, что могу доверять PHP, чтобы никогда не оставлять свой код в состоянии, когда он не может получить мьютекс, потому что сеанс, который его схватил, был либо изящно, либо безжалостно завершен.
Я рассмотрел использование подхода MySQL LOCK TABLES
, но там еще больше сомнений, потому что, хотя я доверяю блокировке MySQL больше, чем блокировке PHP, я боюсь, если PHP отменит запрос (с * out * crashing), удерживая Блокировка сеанса MySQL, MySQL может заблокировать таблицу (особенно потому, что я могу легко представить код, который может привести к этому).
Честно говоря, мне было бы очень удобно с очень простым расширением C, где я могу точно видеть, какие вызовы POSIX выполняются, и с какими параметрами для обеспечения точного поведения, которое я хочу... но я не ожидаю письменности этот код.
У кого-нибудь есть какие-либо concurrency -рекомендуемые рекомендации по PHP, которые они хотели бы поделиться?