Здравствуйте.
Есть задача:
Делать выборку из базы по условию. Выборку нужно делать чанками.
Выбираем вместе со связями.
Проходимся циклом по результатам. Вносим необходимые изменения в модели, в том числе и в связанные.
Сохраняем.
Используем транзакции.
Реализация на 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Ы транзакций?
Или может есть какие-то ещё плюсы и,или недостатки того или иного подхода?
Спасибо.