Maison >développement back-end >tutoriel php >Opinionated: Comment insérer en toute sécurité plusieurs enregistrements dans plusieurs tables dans Laravel

Opinionated: Comment insérer en toute sécurité plusieurs enregistrements dans plusieurs tables dans Laravel

WBOY
WBOYoriginal
2024-07-17 19:33:34821parcourir

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

Il existe de nombreuses façons de tuer un oiseau. Différentes personnes ont leur façon unique de faire les choses efficacement, c'est pourquoi j'ai ajouté OPINIONATED au sujet, c'est ma façon d'insérer plusieurs enregistrements dans plus d'une table et d'exécuter d'autres services efficacement.

Par exemple, disons que vous souhaitez exécuter un service qui effectue ces tâches sous-répertoriées dans un contrôleur d'enregistrement :

  • Vérifiez si le nouvel utilisateur/client potentiel existe dans la base de données.
  • Enregistrer un utilisateur (il faut bien sûr sauvegarder cet enregistrement dans un tableau).
  • Enregistrez l'événement/l'activité dans un tableau.
  • Enregistrez l'adresse e-mail/le numéro de téléphone du nouvel utilisateur dans une tokens_table pour la vérification du compte.
  • Envoyer un e-mail contenant un jeton qui expirera dans 10 minutes.
  • Envoyer un SMS contenant un token qui expirera dans 10 minutes.

L'essentiel ici est que nous exécutons plusieurs services dans un contrôleur et qu'ils doivent tous s'exécuter avec succès afin que nous n'ayons pas de problème de Transaction partielle.

Une Transaction partielle peut être décrite comme un scénario dans lequel seules certaines parties d'une transaction sont terminées, entraînant une incohérence des données.

Comment pouvons-nous nous assurer que nous évitons cela ?

Nous utilisons la façade Transactions de base de données facilement disponible dans le framework Laravel.

Pour exécuter une transaction de base de données, nous devons informer l'exécuteur de code qu'il s'agit d'une transaction de base de données.

DB::beginTransaction();

Ensuite, nous créons un bloc try-catch afin de pouvoir détecter facilement les erreurs et faire le nécessaire. Le bloc try sera inséré dans la base de données tandis que le bloc catch détectera toutes les erreurs rencontrées.

Pour le contenu du bloc Essayer, nous aurons

  1. Un service pour vérifier si un utilisateur existe.
$checkIfUserExists = $userService->userExists($request->email, $request->phoneNumber);

if ($checkIfUserExists) return errorResponseHelper('fail', 'User exists!');
  1. Un service pour enregistrer un nouvel utilisateur et enregistrer l'activité.
 $userService->registerUser($request);

 LogActivity($request->email, $request->phoneNumber);
  1. Générez un jeton, enregistrez-le dans la table des jetons et envoyez un événement qui est écouté par deux auditeurs VerificationEmailListener ** et **VerificationSMSListener.
 $generateToken = generateTokenHelper();

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

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

Ensuite, la partie la plus importante de ce bloc TRY est de valider ces modifications si tous les services s'exécutent avec succès et renvoient une réponse réussie.

 DB::commit();

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

Si tous les services de ce bloc try réussissent, la validation de la base de données enregistrera ces transactions dans la base de données.

Regardons maintenant la partie du bloc Catch.

Si une transaction/un service échoue dans le bloc TRY, il arrivera au bloc catch. Nous appellerons donc à nouveau la façade DB pour annuler chaque transaction qui a été insérée dans la base de données comme ceci :

DB::rollBack();

return errorResponseHelper('fail', "Operation not successful, please retry");

La façade DB::rollBack() annulera/annulera chaque transaction qui a été insérée dans la base de données sans problème en quelques millisecondes.

C'est ainsi que je me protège contre l'incohérence des données, en particulier lorsque j'exécute plus d'une transaction de base de données dans Laravel.

Le bloc de code complet :

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");
        }

Si vous avez des questions, n'hésitez pas à laisser tomber.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:. Tableau de correctifsArticle suivant:. Tableau de correctifs