Transactional Job Middleware (Laravel)

Bardzo często w projektach Laravel widzę transakcję dosłownie wszędzie. Laravel już nawet poradził sobie z problem i jeżeli zdefiniujemy transakcję kilka razy w ciągu jednego request’u to wykona się tylko raz ta zdefinowaną „najwyżej”. Jak uniknąć DB::transaction() w kodzie aplikacji?

Konfiguracja w AppProviders w funkcji boot

public function boot(): void
{
  Bus::pipeThrough([
    UseDatabaseTransactions::class,
  ]);
}

Middleware class

class UseDatabaseTransactions
{
    public function handle($command, $next)
    {
        if (! $command instanceof TransactionalJobInterface)  {
            return $next($command);
        }

        return DB::transaction(function () use ($command, $next) {
            return $next($command);
        });
    }
}

Konkretny job który potrzebuje transakcji na poziomie bazy danych

class CreateUserJob implements TransactionalJobInterface
{
    public function handle(): void
    { // do something }
}

Oczywiście interface to tylko szczegół implementacyjny, możesz użyć atrybutu lub w ogóle pominąć to i włączyć transakcje dla wszystkich Jobs.

Scroll to Top