[php] Laravel Eloquent ORM 거래

Eloquent ORM은 꽤 훌륭하지만, PDO와 같은 방식으로 innoDB를 사용하여 MySQL 트랜잭션을 설정하는 쉬운 방법이 있는지, 아니면 ORM을 확장해야 할 수 있는지 궁금합니다.



답변

다음과 같이 할 수 있습니다.

DB::transaction(function() {
      //
});

Closure 내부의 모든 것은 트랜잭션 내에서 실행됩니다. 예외가 발생하면 자동으로 롤백됩니다.


답변

익명 함수가 마음에 들지 않는 경우 :

try {
    DB::connection()->pdo->beginTransaction();
    // database queries here
    DB::connection()->pdo->commit();
} catch (\PDOException $e) {
    // Woopsy
    DB::connection()->pdo->rollBack();
}

업데이트 : laravel 4의 경우 pdo객체가 더 이상 공개되지 않으므로 :

try {
    DB::beginTransaction();
    // database queries here
    DB::commit();
} catch (\PDOException $e) {
    // Woopsy
    DB::rollBack();
}


답변

Eloquent를 사용하고 싶다면 이것을 사용할 수도 있습니다.

이것은 내 프로젝트의 샘플 코드입니다.

        /*
         * Saving Question
         */
        $question = new Question;
        $questionCategory = new QuestionCategory;

        /*
         * Insert new record for question
         */
        $question->title = $title;
        $question->user_id = Auth::user()->user_id;
        $question->description = $description;
        $question->time_post = date('Y-m-d H:i:s');

        if(Input::has('expiredtime'))
            $question->expired_time = Input::get('expiredtime');

        $questionCategory->category_id = $category;
        $questionCategory->time_added = date('Y-m-d H:i:s');

        DB::transaction(function() use ($question, $questionCategory) {

            $question->save();

            /*
             * insert new record for question category
             */
            $questionCategory->question_id = $question->id;
            $questionCategory->save();
        });


답변

클로저를 피하고 싶고 파사드를 기꺼이 사용하고 싶다면 다음은 일을 멋지고 깨끗하게 유지합니다.

try {
    \DB::beginTransaction();

    $user = \Auth::user();
    $user->fill($request->all());
    $user->push();

    \DB::commit();

} catch (Throwable $e) {
    \DB::rollback();
}

명령문이 실패하면 커밋이 적중되지 않고 트랜잭션이 처리되지 않습니다.


답변

나는 당신이 클로저 솔루션을 찾고 있지 않다는 것을 확신합니다. 더 컴팩트 한 솔루션을 위해 이것을 시도하십시오.

 try{
    DB::beginTransaction();

    /*
     * Your DB code
     * */

    DB::commit();
}catch(\Exception $e){
    DB::rollback();
}


답변

어떤 이유로 어디서든이 정보를 찾기가 매우 어려웠 기 때문에 Eloquent 트랜잭션과 관련된 내 문제가 정확히 이것을 바꾸고 있었기 때문에 여기에 게시하기로 결정했습니다.

stackoverflow 답변을 읽은 후 데이터베이스 테이블이 InnoDB 대신 MyISAM을 사용하고 있음을 깨달았습니다.

트랜잭션이 Laravel (또는 보이는 다른 곳)에서 작동하려면 테이블이 InnoDB를 사용하도록 설정되어 있어야합니다.

왜?

MySQL 트랜잭션 및 원자 작업 문서 인용 ( 여기 ) :

MySQL Server (버전 3.23-max 및 모든 버전 4.0 이상)는 InnoDB 및 BDB 트랜잭션 스토리지 엔진과의 트랜잭션을 지원합니다. InnoDB는 완전한 ACID 준수를 제공합니다. 14 장, 스토리지 엔진을 참조하십시오. 트랜잭션 오류 처리와 관련하여 표준 SQL과 InnoDB의 차이점에 대한 자세한 내용은 14.2.11 절,“InnoDB 오류 처리”를 참조하십시오.

MySQL Server의 다른 비 트랜잭션 스토리지 엔진 (예 : MyISAM)은 “원자 적 작업”이라는 데이터 무결성에 대한 다른 패러다임을 따릅니다. 트랜잭션 측면에서 MyISAM 테이블은 효과적으로 항상 autocommit = 1 모드에서 작동합니다. 원자 적 작업은 종종 더 높은 성능과 비슷한 무결성을 제공합니다.

MySQL Server는 두 가지 패러다임을 모두 지원하므로 원자 적 작업의 속도 또는 트랜잭션 기능의 사용 중 애플리케이션이 최상의 서비스를 제공하는지 결정할 수 있습니다. 이 선택은 테이블별로 할 수 있습니다.


답변

예외가 발생하면 트랜잭션이 자동으로 롤백됩니다.

라 라벨 기본 거래 형식

    try{
    DB::beginTransaction();

    /*
    * SQL operation one
    * SQL operation two
    ..................
    ..................
    * SQL operation n */


    DB::commit();
   /* Transaction successful. */
}catch(\Exception $e){

    DB::rollback();
    /* Transaction failed. */
}