Nouveau dans Laravel 13.38. Une application qui lit sur un réplica et écrit sur la base principale a un défaut bien connu : le réplica a quelques secondes de retard. Un visiteur enregistre son pseudo, la page se recharge… et affiche l'ancien. L'option sticky n'y peut rien : elle ne vaut que pour la requête qui a écrit, et la redirection en ouvre une autre.
PreventStaleDatabaseReads
Ce middleware note dans la session l'heure de la dernière écriture. Pendant quelques secondes, les lectures de ce visiteur vont à la base principale ; celles des autres restent sur le réplica.
use Illuminate\Foundation\Http\Middleware\PreventStaleDatabaseReads; Route::middleware(PreventStaleDatabaseReads::for(10))->group(function () { Route::get('/posts/{post}', [PostController::class, 'show']); Route::put('/posts/{post}', [PostController::class, 'update']); });
Sans for(), la fenêtre dure deux secondes. Le middleware a besoin d'une session, et ne suit que la connexion par défaut.
DB::usingWritePdo()
Sans session, par exemple pour un webhook, on demande la base principale pour un bloc de code. Toutes les lectures de la fonction y vont, relations chargées comprises, puis la connexion reprend son réglage, même en cas d'exception :
$commande = DB::usingWritePdo(fn () => Commande::where('reference', $reference)->firstOrFail());
À faire
Ici, le réplica est un second fichier SQLite, qu'on ne recopie qu'à la main (php artisan replique:synchroniser).
- Dans l'aperçu, changez votre pseudo : la page affiche l'ancien. Le réplica a jusqu'à cinq secondes de retard. Faites en sorte qu'un visiteur qui vient d'écrire lise la base principale pendant cinq secondes.
- Le prestataire de paiement appelle
POST /api/webhooks/paiementmoins d'une seconde après la création de la commande, qui n'est pas encore sur le réplica : le webhook répond 404. Faites-lui lire la commande et ses lignes sur la base principale.