개발 Q&A

제목 CI3 + mysql 트랜잭션 문의
카테고리 DB
글쓴이 봉이김선달 작성시각 2019/12/11 23:54:28
댓글 : 1 추천 : 0 스크랩 : 0 조회수 : 9045   RSS

CI3로 개발중에 있습니다.

데이터베이스는 mysql 입니다. innodb 사용중이며, SHOW VARIABLES WHERE VARIABLE_NAME='tx_isolation'로 확인결과 repeatable-read 이며 SELECT @@AUTOCOMMIT; 로 확인결과 1 입니다. (즉 repeatable read 트랜잭션과 autocommit 상태입니다.)

학생 테이블과 학생의 용돈을 저장하는 테이블이 있습니다. (첨부 파일참조)

 

"홍길동"과 "홍길자"는 각 2,000원을 가지고 있고 "홍길동"이라는 학생이 1000원을 "홍길자"라는 학생에게 주었을시 홍길동의 money.won 에는 기존 금액에서 -1000을 계산해서 넣어야 하고, 홍길자의 money.won에는 +1000원을 해서 넣어야 합니다.

 

이 경우 하나의 Controller Function에서 동일 model의 함수를 불러와 작업 수행시 LOCK이 걸리는지 제대로 수행되지 않습니다. SQLyog 등의 Tool에서 각 SQL 2개를 실제로 돌리면 제대로 데이터가 들어가서 SQL에는 문제가 없는것 같습니다.

 

코드는 아래와 같으며, 해당 코드는 글을 남기기위해 작성한 임시코드로 실제 문제가 되는 코드의 축약본입니다.

transaction 부분 start, commit, rollback 부분을 지우고 실행해도 수행되지 않습니다.

어느 부분에 문제가 있는지 조언을 부탁드립니다.

 

//Controller

class Money extends MY_Controller {

   public function update_money(){

       $this->db->trans_start();

       $student_id1 = 1; //홍길동

       $student_id2 = 2; //홍길자

       $money1 = 1000; //홍길동의 돈

       $money2 = 3000; //홍길자의 돈

       $data1 = array( 'won' => $money1 );

       $data2 = array( 'won' => $money2 );

       $result = $this->money_model->edit($data1, $student_id1); // 홍길동에게 돈 1000원 차감

       $result2 = $this->money_model->edit($data2, $student_id2); // 홍길자에게 돈 1000원 증가



      if( $result && $result2 ){

          console.log("홍길동이 홍길자에게 1000원을 주었습니다.");    

          $this->db->trans_commit();

      }else{

          $this->db->trans_rollback();

      }

   }

}



//model

class Money_model extends CI_Model {

    public function edit($data, $student_id){

       $this->db->where('student_id', $student_id);

       $this->db->update('money', $data);

       return ($this->db->affected_rows() > 0) ? TRUE : FALSE;

    }

}

 


태그 트랜잭션,LOCK,CI3
첨부파일 table.png (11.5 KB)
 다음글 facebook 이나 insta 같은 게시글 리스트 구... (2)
 이전글 DB연결 질문드립니다. (1)

댓글

한대승(불의회상) / 2019/12/12 09:48:05 / 추천 0
$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');
$this->db->trans_complete();

가이드에도 나와 있듯이 trans_start()로 시작하면 trans_complete()로 끝내야합니다.

수동으로 점검하고 싶다면 trans_begin()으로 시작하세요.

$this->db->trans_begin();

$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');

if ($this->db->trans_status() === FALSE)
{
        $this->db->trans_rollback();
}
else
{
        $this->db->trans_commit();
}