developer tip

Laravel Eloquent ORM 거래

copycodes 2020. 9. 17. 08:03
반응형

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

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

\DB::beginTransaction();

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

\DB::commit();

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


I'm Sure you are not looking for a closure solution, try this for a more compact solution

 try{
    DB::beginTransaction();

    /*
     * Your DB code
     * */

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

For some reason it is quite difficult to find this information anywhere, so I decided to post it here, as my issue, while related to Eloquent transactions, was exactly changing this.

After reading THIS stackoverflow answer, I realized my database tables were using MyISAM instead of InnoDB.

For transactions to work on Laravel (or anywhere else as it seems), it is required that your tables are set to use InnoDB

Why?

Quoting MySQL Transactions and Atomic Operations docs (here):

MySQL Server (version 3.23-max and all versions 4.0 and above) supports transactions with the InnoDB and BDB transactional storage engines. InnoDB provides full ACID compliance. See Chapter 14, Storage Engines. For information about InnoDB differences from standard SQL with regard to treatment of transaction errors, see Section 14.2.11, “InnoDB Error Handling”.

The other nontransactional storage engines in MySQL Server (such as MyISAM) follow a different paradigm for data integrity called “atomic operations.” In transactional terms, MyISAM tables effectively always operate in autocommit = 1 mode. Atomic operations often offer comparable integrity with higher performance.

Because MySQL Server supports both paradigms, you can decide whether your applications are best served by the speed of atomic operations or the use of transactional features. This choice can be made on a per-table basis.


If any exception occurs, the transaction will rollback automatically.

Laravel Basic transaction format

    try{
    DB::beginTransaction();

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


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

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

참고URL : https://stackoverflow.com/questions/15105640/laravel-eloquent-orm-transactions

반응형