Laravel で Database 接続にトランザクションを用いる

Laravel を使ったDBアプリケーションでトランザクションを使用する方法を紹介します。

Laravel でDB接続を行う際に トランザクションを利用したいケースは多々あるかと思います。

Laravel でトランザクションを実施する際には DB クラスを使用します。

DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);

    DB::table('posts')->delete();
});

上記のように記述することで、クロージャ内の処理は自動的に トランザクションにラップされます。

または単に

DB::beginTransaction();

と実施することで、トランザクションを開始することができます。

ロールバックする際には、DB::rollBack を、 コミットする際には DB::commit を実施します。

DB::rollBack();
DB::commit();

アプリケーション全体でトランザクションを有効にするには、以下のようなミドルウェアを用意すると良いでしょう。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\DB;

class DBTransaction
{
    public function handle($request, Closure $next, $guard = null)
    {
        DB::beginTransaction();
        $response = $next($request);
        DB::commit();
        return $response;
    }
}

DBエラーに反応して、開始されたトランザクションをロールバックする際には、\App\Exceptions\Handler::render で以下のように 記述します。

    public function render($request, Exception $exception)
    {
        if (DB::transactionLevel() > 0) {
            DB::rollback();
        }
        parent::render($request, Exception $exception);
    }

ValidationError など手動でキャッチする例外処理時のロールバックには、
それぞれDB::rollback() をコールするようにしてください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です