Laravel では、データベース トランザクションで一連の操作を実行する場合、DB ファサードでトランザクション メソッドを使用できます。トランザクションのクロージャ内で例外がスローされた場合、トランザクションは自動的に復元されます。クロージャが正常に実行されると、トランザクションは自動的にコミットされます。トランザクション メソッドを使用する場合、トランザクションを手動で元に戻したりコミットしたりすることを心配する必要はありません:
DB::transaction(function () { DB::table('users')->update(['votes' => 1]); DB::table('posts')->delete(); });
トランザクションを手動で操作する
トランザクションを手動で処理し、復元またはコミット操作を完全に制御したい場合は、DB を使用できます。 facadebeginTransaction
メソッド:
DB::beginTransaction();
rollBack メソッドを使用してトランザクションを復元することもできます:
DB::rollBack();
最後に、commit メソッドを使用してトランザクションを送信できます:
DB::commit();
注: DB ファサードのトランザクション メソッドは、次の目的にも使用できます。クエリ ステートメント ビルダーと Eloquent ORM トランザクションを制御します。
ナレッジ ポイントをデータベースに保存するとします。このナレッジ ポイントは、同時に 2 つの異なるテスト ポイントに属します。つまり、テスト ポイントとナレッジ ポイントの 2 つのデータは多対多です。次に、この種のデータを実装する必要があります。 この構造には 3 つのテーブルが必要です:
ナレッジ ポイント テーブル wiki:
--------------------------------------- id title content ---------------------------------------
テスト ポイント テーブル タグ:
------------------- id name -------------------
テスト ポイント ナレッジ ポイント関連付けテーブル wiki_tag_rel
---------------------------------- id tag_id wiki_id ----------------------------------
次に、開く必要があります。 Wiki データを追加するためのトランザクションを実行し、Wiki が正常に追加された後に追加します。失敗)
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Database\QueryException; use App\Wiki; class TestController extends Controller { //用DB facade的事务方法控制 查询语句构建器的事务 public function storeWiki(Request $request) { DB::beginTransaction(); try { $tagIds = explode(',', $request->get('tag_id')); $wiki_id = DB::table('wiki')->insertGetId([ 'title' => $request->get('title'), 'content' => $request->get('content') ]); $relationData = []; foreach($tagIds as $tagId) { $data = ['wiki_id' => $wiki_id, 'tag_id' => $tagId]; $relationData[] = $data; } DB::table('wiki_tag_rel')->insert($relationData); DB::commit(); } catch(\Illuminate\Database\QueryException $ex) { DB::rollback(); return \Response::json(['status' => 'error', 'error_msg' => 'Failed, please contact supervisor']); } return \Response::json(['status' => 'ok']); } //用DB facade的事务方法控制 Eloquent ORM的事务 public function createWiki(array $data) { DB::beginTransaction(); try { $tagIds = explode(',', $data['tag_id']); $newWiki = Wiki::create([ 'title' => $data['title'], 'content' => $data['content'] ]); //Wiki和Tag两个Model使用了belongsToMany建立了多对多的关系 //通过attach方法来附加wiki和tag的关系(写入中间表) $newWiki->tags()->attach($tagIds); DB::commit(); } catch(QueryException $ex) { DB::rollback(); return \Response::json(['status' => 'error', 'error_msg' => 'Failed, please contact supervisor']); } return \Response::json(['status' => 'ok']); } }
説明
Laravelでは、データベーストランザクションで一連の操作を実行したい場合、DBファサードでトランザクションメソッドを使用できます。トランザクションのクロージャ内で例外がスローされた場合、トランザクションは自動的に復元されます。クロージャが正常に実行されると、トランザクションは自動的にコミットされます。トランザクション メソッドを使用する場合、トランザクションを手動で元に戻したりコミットしたりすることを心配する必要はありません:
DB::transaction(function () { DB::table('users')->update(['votes' => 1]); DB::table('posts')->delete(); });
トランザクションを手動で操作する
トランザクションを手動で処理し、復元またはコミット操作を完全に制御したい場合は、DB を使用できます。 facade
メソッド:DB::beginTransaction();
beginTransaction
rollBack メソッドを使用してトランザクションを復元することもできます: DB::rollBack();
最後に、commit メソッドを使用してトランザクションを送信できます:
DB::commit();
注: DB ファサードのトランザクション メソッドは、次の目的にも使用できます。クエリ ステートメント ビルダーと Eloquent ORM トランザクションを制御します。
例
ナレッジ ポイント テーブル wiki:
--------------------------------------- id title content ---------------------------------------
テスト ポイント テーブル タグ:
------------------- id name -------------------
テスト ポイント ナレッジ ポイント関連付けテーブル wiki_tag_rel
---------------------------------- id tag_id wiki_id ----------------------------------
次に、開く必要があります。指定されたテスト ポイント
に関連して Wiki データを追加するトランザクションを実行します (クエリ ビルダーまたは Eloquent ORM を使用して Laravel でクエリを実行する場合、IlluminateDatabaseQueryException 例外が返されます)。失敗します)
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Database\QueryException; use App\Wiki; class TestController extends Controller { //用DB facade的事务方法控制 查询语句构建器的事务 public function storeWiki(Request $request) { DB::beginTransaction(); try { $tagIds = explode(',', $request->get('tag_id')); $wiki_id = DB::table('wiki')->insertGetId([ 'title' => $request->get('title'), 'content' => $request->get('content') ]); $relationData = []; foreach($tagIds as $tagId) { $data = ['wiki_id' => $wiki_id, 'tag_id' => $tagId]; $relationData[] = $data; } DB::table('wiki_tag_rel')->insert($relationData); DB::commit(); } catch(\Illuminate\Database\QueryException $ex) { DB::rollback(); return \Response::json(['status' => 'error', 'error_msg' => 'Failed, please contact supervisor']); } return \Response::json(['status' => 'ok']); } //用DB facade的事务方法控制 Eloquent ORM的事务 public function createWiki(array $data) { DB::beginTransaction(); try { $tagIds = explode(',', $data['tag_id']); $newWiki = Wiki::create([ 'title' => $data['title'], 'content' => $data['content'] ]); //Wiki和Tag两个Model使用了belongsToMany建立了多对多的关系 //通过attach方法来附加wiki和tag的关系(写入中间表) $newWiki->tags()->attach($tagIds); DB::commit(); } catch(QueryException $ex) { DB::rollback(); return \Response::json(['status' => 'error', 'error_msg' => 'Failed, please contact supervisor']); } return \Response::json(['status' => 'ok']); } }
Laravel でのデータベース トランザクションの使用とトランザクション失敗後の例外のキャプチャに関連するその他の記事 PHP 中国語 Web サイトにご注意ください。