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
を呼び出して処理をしています。
引数で渡しているクロージャの中の処理が順に行われてます。
上から順に処理が行われて、例外やエラーなどが発生しなかった場合に、データベースにインサート内容が反映されます。
例外などがあって、処理が終わらなかった場合にはデータベースにはインサートされず、ロールバックされます。
コメント