의견: Laravel에서 둘 이상의 테이블에 여러 레코드를 안전하게 삽입하는 방법

WBOY
풀어 주다: 2024-07-17 19:33:34
원래의
789명이 탐색했습니다.

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 블록은 발생한 오류를 포착합니다.

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. 토큰을 생성하고 토큰 테이블에 로그인한 다음 두 리스너 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!