Yii2 защита от race condition

Как в Yii2 можно обезопасить свой код от атаки типа race condition?

Например, в Laravel для SQL запросов есть такая штука как pessimistic locking (https://laravel.com/docs/5.4/queries#pessimistic-locking), которая блокирует данные от модификации до окончания транзакции.

Как в этом плане обстоят дела с ActiveQuery? Понятно, что PHP из коробки ставит все запросы для одной сессии в очередь (https://rmcreative.ru/blog/post/blokirovanie-sessiy-v-php), но пользователь может зайти с разных браузеров под своими учетными данными, тем самым запустив несколько сессий.

Поэтому вопрос - как защищаться от атак race condition в Yii2 при использовании ActiveQuery?


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

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

yii2 оптимистичнее :) см. yii\db\ActiveRecord::optimisticLock(), подробности в руководстве

→ Ссылка
Автор решения: Егор Банин

Загуглите про блокировки в вашей базе данных по запросу "mysql locks", например. Вы очень быстро обнаружите конструкцию select ... for update|share -- это блокировка выбранных строк в транзакции до завершения этой транзакции. То есть, когда вы делаете select for update строк, которые собираетесь менять, другие транзакции не смогут сделать select for update и update этих строк и будут ждать до завершения первой транзакции. Это функционал sql баз данных, поддерживающих транзакции, вы можете использовать его с любым фрэймворком и с нативным php. Методы lockForUpdate и sharedLock, на которые вы ссылаетесь, просто обёртка для этого функционала базы.

Теперь вам остаётся нагуглить как делать select for update в Yii2. В общем случае вам надо просто добавить к select-запросу for update и выполнять его в одной транзакции с запросом на обновление. Этот метод решает проблему с гонкой при обновлении данных в базе (кажется то, что вам нужно).

→ Ссылка