#php #laravel #eloquent #concurrency #transactions
#php #laravel #eloquent #параллелизм #транзакции
Вопрос:
В моем коде у меня есть существующая красноречивая модель. Я хочу атомарно:
- загрузите его новую копию из базы данных и
- если его состояние соответствует ожидаемому, обновите один столбец.
Я написал следующий код:
private function getRefreshedAndUpdated(MyEloquentModel $old_model)
{
$id = $old_model->id;
$new_model = null;
DB::transaction(function () use ($id, amp;$new_model) {
$new_model = MyEloquentModel::lockForUpdate()->find($id);
if ($new_model->state !== 'READY') {
throw new Exception('Model not ready');
}
$new_model->state = 'UPDATED';
$new_model->save();
});
return $new_model;
}
Выполняет ли это то, что я хочу?
В частности, гарантирую ли я, что MyEloquentModel::lockForUpdate()->find($id)
:
- всегда будет извлекать модель свежей из БД (пропуская любой кэш, возможно, заполненный выборкой
$old_model
ранее)? - заблокирует ли он предотвращение каких-либо изменений, например, через
$old_model
(через pthreads) или базовую запись БД в другом процессе?
Я подозреваю, что так и будет, но это для некоторого критического кода, поэтому нужно перепроверить.
Комментарии:
1.
fresh
refresh
кстати, в модели есть методы and2. Вы также можете использовать кеш для создания атомарных блокировок .
3. @lagbox Большое спасибо, я знал об их существовании. Однако я не знаю, предлагают ли они гарантии, которые я ищу здесь. Вы знаете?
4. @DigitalDrifter Спасибо. Я ищу что-то более фундаментальное — на уровне БД.