@KBBS

Если обрабатывать множество запросов к БД в цикле, насколько правильным будет заворачивать в транзакцию каждую итерацию?

Здравствуйте.

Есть задача:
Делать выборку из базы по условию. Выборку нужно делать чанками.
Выбираем вместе со связями.
Проходимся циклом по результатам. Вносим необходимые изменения в модели, в том числе и в связанные.
Сохраняем.
Используем транзакции.

Реализация на Laravel, но в данном случае это не особо важно.

Я заключал в транзакцию работу со всем чанком. Но мне сказали, что это не правильно и нужно заключать в транзакцию обработку каждой записи.

Ниже приведу исправленный код.
Я не буду приводить полный фрагмент, опишу больше схематически.
Это я к тому, что пускай не смущают производимые действия. Важна сама логика.

// Получаем данные с разбивкой на чанки.
MyModel::query()
    ->where('active', true)
    ->with('rel1', 'rel2')
    ->chunkById(200, function ($chunk) {
    // Обрабатываем чанк.
    foreach ($chunk as $record) {
        try {
            // На каждой итерации обрабатываем один элемент чанка в отдельной транзакции.
            // Если что-то идёт неправильно, ловим исключение по каждому случаю.
            $record::resolveConnection()->transaction(function () use ($record) {
                $record->rel1->value = $record->rel1->value / 100 * 5;
                $record->rel2->value = Str::random(10);
                $record->step += 1;
                $record->active = $record->step < 5;
                $record->push();
            }, 3);
        } catch (Throwable $e) {
            // Что-то делаем...
        }
    }
});


В целом, такой подход имеет смысл.
Но не будут ли вызывать проблемы с производительностью постоянные beginЫ и commitЫ транзакций?

Или может есть какие-то ещё плюсы и,или недостатки того или иного подхода?

Спасибо.
  • Вопрос задан
  • 77 просмотров
Решения вопроса 1
@FanatPHP
Чебуратор тега PHP
Логика зависит от логики.

Ты должен спросить себя: если что-то пошло не так при обработке одной записи, то надо откатить изменения связанные только с этой записью, или со всем чанком?
И получишь ответ на свой вопрос

Если все равно, то лучше весь чанк.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы