---
title: "Laravel Chores: відновлювані операції з даними та автоматизація рутинних завдань"
url: https://laravelukraine.com/blog/laravel-chores-vidnovliuvani-operaciyi-z-danimi-ta-avtomatizaciia-rutinnix-zavdan
date: 2026-08-19
source: https://laravel-news.com/laravel-chores?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+laravelnews
---

# Laravel Chores: відновлювані операції з даними та автоматизація рутинних завдань

Новий пакет Laravel Chores від [Amr Lotfy Saleh](https://github.com/AmrLotfy) розв'язує типову проблему масових операцій з даними: коли обробка мільйонів записів перервалася через перезапуск сервера, важко визначити, на якому саме записі зупинилися. Пакет обгортає одноразові операції з даними в пачки (batches), які зберігають прогрес у базі даних після кожної пачки. Якщо процес переривається, наступний запуск продовжить роботу з того місця, де зупинився, замість того щоб починати спочатку. Дизайн пакету натхненний гемом maintenance_tasks для Rails від Shopify.

## Ключові можливості

Пакет надає такий функціонал:

- **Збереження прогресу (checkpointed progress)** - ID останнього обробленого запису записується в таблицю `chore_runs` після кожної пачки, тому аварійне завершення або Ctrl+C втрачає максимум одну пачку прогресу
- **Keyset pagination** - пачки обробляються за первинним ключем, а не за offset, що уникає класичної помилки, коли оновлення рядків зміщує їх з частини, яку ви ітеруєте
- **Ізоляція помилок** - запис, що викликає виняток, логується в таблицю збоїв і пропускається, а виконання продовжується
- **Без додаткової інфраструктури** - стан зберігається у вашій базі даних, без потреби в Redis, queue workers або зовнішніх сервісах
- **Шість Artisan-команд** - створення шаблону, запуск, список, пауза, перегляд збоїв та повторна спроба
- **CI-friendly вивід** - режим JSON-виводу та чіткі коди виходу: `0` для чистого завершення, `1` для завершення зі збоями, `2` для фатальної помилки

## Створення Chore

Chore - це клас з двома методами: `collection()` повертає запит для записів, які потрібно обробити, а `process()` обробляє один запис. Створити шаблон можна командою `php artisan make:chore`:

```php
namespace App\Chores;

use AmrLotfy\Chores\Chore;
use App\Models\User;
use Illuminate\Contracts\Database\Eloquent\Builder;

class NormalizePhoneNumbers extends Chore
{
    public int $batchSize = 500;

    public function collection(): Builder
    {
        return User::whereNotNull('phone')
            ->where('phone', 'not like', '+%');
    }

    public function process($record): void
    {
        $record->update([
            'phone' => PhoneNumber::parse($record->phone, 'EG')->toE164(),
        ]);
    }
}
```

Це весь клас. Розбиття на пачки, відстеження прогресу та логування помилок відбуваються автоматично. Розмір пачки за замовчуванням становить 500 записів через конфігураційний файл, якщо ви не вказали його в класі.

## Запуск, пауза та відновлення

Команда `chore:run` виконує chore з відображенням прогресу в реальному часі в терміналі:

```bash
php artisan chore:run NormalizePhoneNumbers
```

Прогрес зберігається після кожної пачки, тому та сама команда відновлює виконання, яке було перерване через deploy, аварію або Ctrl+C. Команда `chore:pause` зупиняє виконання на межі наступної пачки, а `chore:list` показує доступні chores разом з історією їх виконання.

Одне застереження щодо гарантій: збереження прогресу відбувається після пачки, а не після окремого запису, тому записи всередині пачки, яка виконувалась під час переривання, можуть бути повторно перевірені після відновлення. По можливості пишіть `process()` ідемпотентним - наведений вище приклад з номерами телефонів безпечний, оскільки вже нормалізовані номери більше не відповідають запиту `collection()`.

Для регулярних завдань, таких як очищення застарілих записів, можна використовувати команду разом з [планувальником завдань Laravel](https://laravel-news.com/task-scheduler):

```php
$schedule->command('chore:run PurgeExpiredRecords')->monthly();
```

## Обробка помилок

Запис, що викликає виняток, не зупиняє виконання. Пакет логує запис і виняток у таблицю збоїв, пропускає його та продовжує роботу. Коли виконання завершується, ви можете переглянути та повторно обробити записи зі збоями як окрему операцію:

```bash
php artisan chore:failures NormalizePhoneNumbers
php artisan chore:retry NormalizePhoneNumbers
```

Такий підхід важливий для тривалих операцій: сотня некоректних номерів телефонів з десяти мільйонів не повинна зупиняти чотиригодинне завдання, а повторна обробка сотні записів після виправлення набагато дешевша, ніж повторне виконання всього процесу.

## Технічні особливості та обмеження

Chores виконуються на передньому плані з одним воркером на chore, а колекція потребує упорядковуваного первинного ключа, такого як auto-increment або ULID. Виконання в черзі та паралельні воркери знаходяться в дорожній карті; якщо ви хочете розподілити масове оновлення між queue workers вже сьогодні, пакет [Queue-SQL](https://laravel-news.com/queue-sql-run-mass-deletes-and-updates-across-parallel-queue-jobs) використовує такий підхід.

## Встановлення

Laravel Chores вимагає PHP 8.2+ та Laravel 12 або 13, підтримує MySQL, PostgreSQL та SQLite:

```bash
composer require amrlotfy/laravel-chores
php artisan vendor:publish --tag=chores-migrations
php artisan migrate
```

Конфігураційний файл дозволяє змінити місце розташування класів chore (за замовчуванням `app/Chores`), розмір пачки за замовчуванням, назви таблиць та інтервал паузи між пачками для зменшення навантаження на завантажену базу даних.

Вихідний код, документацію та дорожню карту можна знайти в [репозиторії Laravel Chores на GitHub](https://github.com/AmrLotfy/laravel-chores).
