「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > 意見あり: Laravel で複数のレコードを複数のテーブルに安全に挿入する方法

意見あり: Laravel で複数のレコードを複数のテーブルに安全に挿入する方法

2024 年 8 月 6 日に公開
ブラウズ:687

Opinionated: How to safely insert multiple records to more than one table in Laravel

鳥を殺す方法はたくさんあります。人によって物事を効果的に行う独自の方法があるため、トピックに OPINIONATED を追加しました。これは、複数のレコードを複数のテーブルに挿入し、他のサービスを効果的に実行する私の方法です。

たとえば、以下のリストにあるタスクを登録コントローラーで実行するサービスを実行するとします。

  • 新しいユーザー/潜在顧客がデータベースに存在するかどうかを確認します。
  • ユーザーを登録します (もちろん、このレコードをテーブルに保存する必要があります)。
  • イベント/アクティビティをテーブルに記録します。
  • アカウント確認のために、新しいユーザーのメールアドレス/電話番号を tokens_table に記録します。
  • 10 分で期限切れになるトークンを含むメールを送信します。
  • 有効期限が切れるトークンを含む SMS を送信します 10分で。

ここでの主な要点は、コントローラーで複数のサービスを実行しており、部分トランザクションの問題が発生しないように、それらはすべて正常に実行される必要があるということです。

部分的なトランザクションは、トランザクションの一部のみが完了し、データの不整合が発生するシナリオとして説明できます。

これを確実に回避するにはどうすればよいですか?

Laravel フレームワークですぐに利用できる データベース トランザクション ファサードを使用します。

データベース トランザクションを実行するには、コード実行プログラムにこれがデータベース トランザクションであることを知らせる必要があります。

DB::beginTransaction();

次に、try-catch ブロックを作成して、エラーを簡単にキャッチして必要な処理を実行できるようにします。 try ブロックはデータベースに挿入し、catch ブロックは発生したエラーをキャッチします。

Try ブロックのコンテンツには、

があります。
  1. ユーザーが存在するかどうかを確認するサービス。
$checkIfUserExists = $userService->userExists($request->email, $request->phoneNumber);

if ($checkIfUserExists) return errorResponseHelper('fail', 'User exists!');
  1. 新規ユーザーを登録し、アクティビティを記録するサービス。
 $userService->registerUser($request);

 LogActivity($request->email, $request->phoneNumber);
  1. トークンを生成し、トークン テーブルに記録し、2 つのリスナー VerificationEmailListener ** と **VerificationSMSListener によってリッスンされているイベントをディスパッチします。
 $generateToken = generateTokenHelper();

$userService->tokenLog($request->email, $generateToken[0]);

event(new VerificationTokenDispatch($request->email, $request->PhoneNumber, $generateToken[1]));

次に、この TRY ブロックの最も重要な部分は、すべてのサービスが正常に実行され、成功の応答が返された場合にこれらの変更をコミットすることです。

 DB::commit();

return successResponseHelper('success', "OTP has been sent to your mobile/email, kindly note that OTP validity is 10 minutes");

この try ブロック内のすべてのサービスが成功すると、データベース コミットによってこれらのトランザクションがデータベースに保存されます。

それでは、Catch ブロック部分を見てみましょう。

トランザクション/サービスが TRY ブロックで失敗すると、catch ブロックに進みます。そこで、次のように DB ファサードを再度呼び出して、データベースに挿入されたすべてのトランザクションをロールバックします。

DB::rollBack(); return errorResponseHelper('fail', "操作が成功しませんでした。再試行してください");
DB::rollBack();

return errorResponseHelper('fail', "Operation not successful, please retry");
DB::rollBack() ファサードは、データベースに挿入されたすべてのトランザクションをミリ秒以内に問題なく保存解除/ロールバックします。

これは、特に Laravel で複数のデータベース トランザクションを実行している場合に、データの不整合を防ぐ方法です。

完全なコードブロック:


Illuminate\Support\Facades\DB を使用します。 DB::beginTransaction(); 試す { $checkIfUserExists = $userService->userExists($request->email, $request->phoneNumber); if ($checkIfUserExists) return errorResponseHelper('fail', 'ユーザーが存在します!'); $registerUser = $userService->registerUser($request); LogActivity($request->電子メール、$request->電話番号); $generateToken =generateTokenHelper(); // 配列を返します。最初の配列は暗号化されており、2 番目の配列は暗号化されていません $userService->tokenLog($request->email, $generateToken[0]); イベント(new VerificationTokenDispatch($request->email, $request->PhoneNumber, $generateToken[1])); // SMS リスナーと電子メール リスナーの両方がこのイベントをリッスンしています DB::コミット(); return successResponseHelper('success', "OTP が携帯電話/電子メールに送信されました。OTP の有効期限は 10 分であることに注意してください。"); } catch (\Throwable $th) { DB::rollBack(); return errorResponseHelper('fail', "操作が成功しませんでした。再試行してください"); }
DB::rollBack();

return errorResponseHelper('fail', "Operation not successful, please retry");
ご質問がございましたら、お気軽にお問い合わせください。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/adetolaaremu/opinionated-how-to-safely-insert-multiple-records-to-more-than-one-table-in-laravel-96l?1侵害がある場合は、削除するには[email protected]までご連絡ください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3