По определенному URL приходит уведомление об оплате, мне нужно чтобы логика запустилась 1 раз если их пришло несколько одновременно, использую FileMutex:
if (\Yii::$app->mutex->acquire('order_payment_' . $order->id)) {
// здесь логика которая должна запуститься 1 раз если пришло несколько одновременных запросов
\Yii::$app->mutex->release('order_payment_' . $order->id);
}
Работает, но иногда всё-таки эта логика запускается 2 раза, почему такое может быть? Неужели они в один момент времени лочат файл и друг на друга накладывается? Как этого избежать?
Последний раз редактировалось rumasterov 2016.04.29, 16:14, всего редактировалось 1 раз.
По определенному URL приходит уведомление об оплате, мне нужно чтобы логика запустилась 1 раз если их пришло несколько одновременно, использую FileMutex:
if (\Yii::$app->mutex->acquire('order_payment_' . $order->id)) {
// здесь логика которая должна запуститься 1 раз если пришло несколько одновременных запросов
\Yii::$app->mutex->release('order_payment_' . $order->id);
}
Работает, но иногда всё-таки эта логика запускается 2 раза, почему такое может быть? Неужели они в один момент времени лочат файл и друг на друга накладывается? Как этого избежать?
По определенному URL приходит уведомление об оплате, мне нужно чтобы логика запустилась 1 раз если их пришло несколько одновременно, использую FileMutex:
if (\Yii::$app->mutex->acquire('order_payment_' . $order->id)) {
// здесь логика которая должна запуститься 1 раз если пришло несколько одновременных запросов
\Yii::$app->mutex->release('order_payment_' . $order->id);
}
Работает, но иногда всё-таки эта логика запускается 2 раза, почему такое может быть? Неужели они в один момент времени лочат файл и друг на друга накладывается? Как этого избежать?
2016-04-29 10:03:51 [*][-][-][info][payment] Received notification for order: 1
2016-04-29 10:03:51 [*][-][-][info][payment] Received notification for order: 1
Да и по внутренним логам видно, что логика второй раз запустилась, когда еще первая не закончилась. Такое впечатление, что им обоим одновременно метод acquire вернул true. Но такое не всегда получается, в большинстве случаев второй запрос все-таки не срабатывает. Вот пытаюсь понять с чем это может быть связано.
По определенному URL приходит уведомление об оплате, мне нужно чтобы логика запустилась 1 раз если их пришло несколько одновременно, использую FileMutex:
if (\Yii::$app->mutex->acquire('order_payment_' . $order->id)) {
// здесь логика которая должна запуститься 1 раз если пришло несколько одновременных запросов
\Yii::$app->mutex->release('order_payment_' . $order->id);
}
Работает, но иногда всё-таки эта логика запускается 2 раза, почему такое может быть? Неужели они в один момент времени лочат файл и друг на друга накладывается? Как этого избежать?
2016-04-29 10:03:51 [*][-][-][info][payment] Received notification for order: 1
2016-04-29 10:03:51 [*][-][-][info][payment] Received notification for order: 1
Да и по внутренним логам видно, что логика второй раз запустилась, когда еще первая не закончилась. Такое впечатление, что им обоим одновременно метод acquire вернул true. Но такое не всегда получается, в большинстве случаев второй запрос все-таки не срабатывает. Вот пытаюсь понять с чем это может быть связано.
ну так вообще зачем filemutex использовать? юзайте db. это быстрее.
Разобрался, моя ошибка, я в этой логике в gearman задачу добавляю, которая в фоне выполняется и в случае когда второй запрос чуть позже приходил (на 200 мс), то первый уже успевал выполниться и lock снимался) Добавил небольшой sleep перед снятием лока, теперь запросы которые пришли в ту же секунду увидят что есть lock и не выполнятся.
За рекомендацию использовать MysqlMutex спасибо, теперь его использую.