Level 56
I use a middleware for that:
<?php
namespace App\Http\Middleware;
use Closure;
use Exception;
use Illuminate\Database\ConnectionInterface;
use Symfony\Component\HttpFoundation\Response;
class DbTransaction
{
/** @var \Illuminate\Database\ConnectionInterface */
private $connection;
public function __construct(ConnectionInterface $connection)
{
$this->connection = $connection;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
* @throws \Throwable
*/
public function handle($request, Closure $next)
{
$this->connection->beginTransaction();
try {
$response = $next($request);
} catch (Exception $exception) {
$this->connection->rollBack();
throw $exception;
}
if ($response instanceof Response && $response->getStatusCode() > 399) {
$this->connection->rollBack();
} else {
$this->connection->commit();
}
return $response;
}
}
Add this you controller constructor:
namespace App\Http\Controllers;
use App\Http\Middleware\DbTransaction;
class MyController extends Controller
{
public function __construct()
{
$this->middleware(DbTransaction::class)->only(['store']);
}
// ... controller methods
}
Here I am using the middleware class directly in the controller's constructor, but you can add it to app/Http/Kernel.php with an alias and use the alias.