Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Bernard123's avatar

DB::transaction won't rollback

Hello I want to ask, why my DB::transaction() won't rollback if I'm throwing an error, like

DB::transaction(function () { User::create([ "name" => "..." ]);

        throw ValidationException::withMessages([
            "name" => "..."
        ]);
    });
0 likes
5 replies
jayandholariya's avatar

@bernard123 If you're using Laravel transactions like this, it should work as expected. Just make sure to perform any validation before starting the transaction:

// Perform validation here
DB::beginTransaction();
try {
	User::create([ "name" => "..." ]);
    DB::commit();
} catch (\Exception $e) {
    // Handle transaction failure
    DB::rollBack();
    return response()->json([ 'error' => $e->getMessage()], 500);
}
1 like
Bernard123's avatar

I already fixed it because I forgot to specify the DB::connection, since I have more than two database connections.

srushti_kansagara's avatar

@bernard123 In Laravel, DB::transaction() only rolls back if an uncaught exception happens inside it.

But when you throw ValidationException, Laravel catches it internally to return a validation error response (like 422), so it doesn’t treat it like a crash. That’s why the rollback doesn’t happen.

If you really want it to rollback on validation errors, you should manually use DB::beginTransaction() and DB::rollBack() inside a try-catch. That gives you full control. as the @jayandholariya has suggested

and If you must use DB::transaction() and want validation errors to trigger rollback then :

try {
    DB::transaction(function() {
        User::create([...]);
        // Throw validation error inside:
        throw ValidationException::withMessages([
            'name' => 'This field is required.'
        ]);
    });
} catch (ValidationException $e) {
    // The rollback has already happened ✅
    return back()->withErrors($e->errors());
}
1 like
Tray2's avatar

In short, always validate before you involve the database.

1 like

Please or to participate in this conversation.