Laravelでトランザクションを張る2つの方法!

Laravel Laravel

Laravelでトランザクションを張る方法について書いてみました。
Laravel8 + MySQL8で確認しています。

トランザクションを張る方法は下記の2つです。
・DBのコミットやロールバック自分で書く。
・transactionメソッドを使って、クロージャの中でSQL操作を完結させる。

そもそもトランザクションとは?

簡単に言うと、トランザクションは処理のまとまりのことです。
トランザクションを開始して、コミットされるまでをひとまとまりとして処理します。
エラーが発生したり、例外が投げられた場合は処理をなかったことにして、トランザクションの開始前に戻します。

DBファサードを使用する準備

DBファサードを使用することで、トランザクションを張ることができます。
DBファサードを使用するには、使用したいファイルの頭に下記のようにuse文を追加します。

use Illuminate\Support\Facades\DB;

手動でトランザクションを張る

下記のように書くことで、トランザクションを張ることができます。
beginTransactionメソッドでトランザクションを開始して、commitメソッドでデータベースに反映します。

try {
    DB::beginTransaction();

    User::create([
        'name'     => 'taro',
        'email'    => 'hoge1@example.com',
        'password' => 'password'
    ]);

    User::create([
        'name'     => 'hanako',
        'email'    => 'hoge2@example.com',
        'password' => 'password'
    ]);

    DB::commit();
} catch (Throwable $e) {
    DB::rollBack();
}

解説

DB::beginTransactionでトランザクションを開始します。
DB::commitが呼ばれるまでは、データベースに反映されません。

今回の例はUserテーブルにデータをインサートしているだけです。
もし、複数のインサート処理やいろいろな処理がある場合にcommitまで行かずに処理が止まったりすると、インサートしたデータが反映されずに処理が終わります。
こうすることで、データの整合性を保つことができます。

エラーがあった場合は、catchで掴んでロールバックします。
DB::rollBackを呼ぶことで、トランザクションをロールバックしてくれます。
これまでのデータベースの変更をトランザクションの開始時まで戻してくれます。

クロージャを使用してトランザクションを張る

手動でトランザクションを張ってみましたが、指定したブロックの処理が終わったらコミットしてくれる書き方があります。
下記のように書くことで、クロージャの中の処理が終わるまでコミットされず、終わったらコミットされるようになります。

DB::transaction(function () {
    User::create([
        'name'     => 'taro',
        'email'    => 'hoge@example.com',
        'password' => 'password'
    ]);
});

ちなみに、引数を渡したい場合は下記のようにクロージャにuseを書くといいです。

DB::transaction(function () use($name, $email, $password) {
    User::create([
        'name'     => $name,
        'email'    => $email,
        'password' => $password
    ]);
});

解説

DB::transactionを呼び出して処理をしています。
引数で渡しているクロージャの中の処理が順に行われてます。

上から順に処理が行われて、例外やエラーなどが発生しなかった場合に、データベースにインサート内容が反映されます。
例外などがあって、処理が終わらなかった場合にはデータベースにはインサートされず、ロールバックされます。

コメント

タイトルとURLをコピーしました