1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Laravel】例外処理とトランザクションの使い方

Posted at

本記事では、try/catch構文と、DB::beginTransaction() および DB::transaction() の使い分けについて、具体例とともに解説します。

try/catch:例外をキャッチして適切に処理する

try/catch構文は、処理中に発生する例外(Exception)をキャッチして、アプリケーションがエラーで落ちるのを防ぐために使用します。

例:

try {
    $user = User::findOrFail(1); // ユーザーが存在しない場合、例外が発生
    return response()->json(['user' => $user]);
} catch (\Exception $e) {
    return response()->json(['error' => 'User not found'], 404);
}
  • findOrFail() は、該当するデータがない場合に ModelNotFoundException をスローします。
  • catch ブロックで例外をキャッチし、適切なレスポンスを返します。

DB::beginTransaction():手動でトランザクションを管理する

トランザクションは、複数のDB操作をまとめて一つの単位として管理したいときに使います。処理が途中で失敗しても、DBを安全な状態に保てます。

例: ユーザー登録とプロフィール作成をトランザクションで管理する

use Illuminate\Support\Facades\DB;
use App\Models\User;
use App\Models\Profile;

try {
    DB::beginTransaction(); // トランザクション開始

    $user = User::create([
        'name' => 'John Doe',
        'email' => 'john@example.com',
        'password' => bcrypt('password'),
    ]);

    Profile::create([
        'user_id' => $user->id,
        'bio' => 'Software Developer',
    ]);

    DB::commit(); // 成功したら確定

    return response()->json(['message' => 'User created successfully']);
} catch (\Exception $e) {
    DB::rollBack(); // 失敗したらロールバック

    return response()->json(['error' => 'Failed to create user'], 500);
}

解説

  1. DB::beginTransaction() で処理開始
  2. 複数の create() を行う
  3. 途中でエラーが出たら DB::rollBack() で巻き戻す
  4. 成功時のみ DB::commit() で確定

明示的な制御ができる反面、記述量が増えるデメリットあり

DB::transaction():自動でトランザクション管理してくれる便利メソッド

Laravelには DB::transaction() メソッドがあり、トランザクションを自動的に try/catch で処理してくれます。

例:自動でロールバックされるトランザクション

use Illuminate\Support\Facades\DB;

DB::transaction(function () {
    $user = User::create([
        'name' => 'John Doe',
        'email' => 'john@example.com',
        'password' => bcrypt('password'),
    ]);

    Profile::create([
        'user_id' => $user->id,
        'bio' => 'Software Developer',
    ]);
});

メリット

  • try/catchを書かなくても自動でロールバック
  • コードがスッキリ

カスタムエラーハンドリングをしたいときは try/catch 併用

  • エラーごとに処理を変えたい
  • エラー内容をログに記録したい
  • 成功後に通知やメールを送信したい
  • 一時的な失敗にリトライ処理を入れたい

DB::transaction() × try/catch:高度なエラーハンドリングも可能

例:ログ出力を伴うエラーハンドリング

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

try {
    $user = DB::transaction(function () {
        $user = User::create([
            'name' => 'Jane Doe',
            'email' => 'jane@example.com',
            'password' => bcrypt('password'),
        ]);

        Profile::create([
            'user_id' => $user->id,
            'bio' => 'Web Designer',
        ]);

        return $user;
    });

    return response()->json(['user' => $user]);
} catch (\Exception $e) {
    Log::error('User creation failed: ' . $e->getMessage());

    return response()->json(['error' => 'User creation failed'], 500);
}
  • DB::transaction() 内で処理を行い、例外が発生すれば自動でロールバック
  • catch でログにエラーを記録し、適切なレスポンスを返す

まとめ

  • try/catch は例外処理を行い、エラーハンドリングに使用
  • DB::beginTransaction() はデータの一貫性を保つために手動でトランザクションを管理
  • DB::transaction() は try/catch を省略でき、自動でロールバックされるため簡潔に書ける
1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?