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

WBOY
リリース: 2024-07-17 19:33:34
オリジナル
805 人が閲覧しました

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

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

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

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

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

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

これに対して確実に指導するにはどうすればよいですか?

Laravel フレームワークですぐに利用できる Database Transactions ファサードを使用します。

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

DB::beginTransaction();
ログイン後にコピー

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

試してみる ブロックの内容については、

を参照してください。
  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', "Operation not successful, please retry");
ログイン後にコピー

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

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

完全なコードブロック:

use Illuminate\Support\Facades\DB;


 DB::beginTransaction();

        try {
            $checkIfUserExists = $userService->userExists($request->email, $request->phoneNumber);

            if ($checkIfUserExists) return errorResponseHelper('fail', 'User exists!');

            $registerUser = $userService->registerUser($request);

            LogActivity($request->email, $request->phoneNumber);

            $generateToken = generateTokenHelper(); // returns an array, the first is encrypted the second is not

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

            event(new VerificationTokenDispatch($request->email, $request->PhoneNumber, $generateToken[1])); // both SMS listeners and email listeners are listening to this event

            DB::commit();

            return successResponseHelper('success', "OTP has been sent to your mobile/email, kindly note that OTP validity is 10 minutes");
        } catch (\Throwable $th) {
            DB::rollBack();
            return errorResponseHelper('fail', "Operation not successful, please retry");
        }
ログイン後にコピー

ご質問がございましたら、お気軽にお問い合わせください。

以上が意見あり: Laravel で複数のレコードを複数のテーブルに安全に挿入する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート