User::select(
'users.id as user_id',
'bonus.level',
'bonus.updated_at',
)
->leftJoin('bonus', 'users.id', '=', 'bonus.user_id')
->where('bonus.level', '>', '0')
->chunkById(100, function ($users) {
foreach ($users as $user) {
// Тут манипуляции с данными, у каждого пользователя свой уровень бонуса, расчеты и т.д.
$bonus = '?';
\DB::transaction(function () use ($user, $bonus) {
Coins::where('user_id', $user->user_id)->update([
'count' => \DB::raw("count+$bonus"),
]);
CoinsHistory::create([
'user_id' => $user->user_id,
'count' => $bonus,
]);
}, 5);
}
}, 'users.id', 'user_id');
Как можно ускорить выполнение этого кода? Сейчас выполняется около 5 минут (100000 пользователей)
Пока печатал, возник еще один вопрос, не перепишут ли друг друга данные если одновременно будут добавляться бонусы?
Не в курсе как работают блокировки в БД и без понятия как проверить возможность таких ошибок
Нужно ли использовать lockForUpdate()
Coins::lockForUpdate()->where('user_id', $user->user_id)->update([
'count' => \DB::raw("count+$bonus"),
]);
Вместо
Coins::where('user_id', $user->user_id)->update([
'count' => \DB::raw("count+$bonus"),
]);