2014-06-06 4 views
0

아래 코드가 있습니다. 트랜잭션이 실패하면 롤백되지 않습니다. 잠금 테이블 문을 제거하면 롤백됩니다. 자물쇠 및 거래를 사용하기 위해해야 ​​할 특별한 것이 있습니까?php/mysql 트랜잭션이 실패시 롤백되지 않습니다 (Codeigniter 프레임 워크)

function save ($items,$customer_id,$employee_id,$comment,$show_comment_on_receipt,$payments,$sale_id=false, $suspended = 0, $cc_ref_no = '', $auth_code = '', $change_sale_date=false,$balance=0, $store_account_payment = 0) 
{ 
    if(count($items)==0) 
     return -1; 

    $sales_data = array(
     'customer_id'=> $this->Customer->exists($customer_id) ? $customer_id : null, 
     'employee_id'=>$employee_id, 
     'payment_type'=>$payment_types, 
     'comment'=>$comment, 
     'show_comment_on_receipt'=> $show_comment_on_receipt ? $show_comment_on_receipt : 0, 
     'suspended'=>$suspended, 
     'deleted' => 0, 
     'deleted_by' => NULL, 
     'cc_ref_no' => $cc_ref_no, 
     'auth_code' => $auth_code, 
     'location_id' => $this->Employee->get_logged_in_employee_current_location_id(), 
     'store_account_payment' => $store_account_payment, 
    ); 

    $this->db->trans_start(); 

    //Lock tables invovled in sale transaction so we don't have deadlock 
    $this->db->query('LOCK TABLES '.$this->db->dbprefix('customers').' WRITE, '.$this->db->dbprefix('sales').' WRITE, 
    '.$this->db->dbprefix('store_accounts').' WRITE, '.$this->db->dbprefix('sales_payments').' WRITE, '.$this->db->dbprefix('sales_items').' WRITE, 
    '.$this->db->dbprefix('giftcards').' WRITE, '.$this->db->dbprefix('location_items').' WRITE, 
    '.$this->db->dbprefix('inventory').' WRITE, '.$this->db->dbprefix('sales_items_taxes').' WRITE, 
    '.$this->db->dbprefix('sales_item_kits').' WRITE, '.$this->db->dbprefix('sales_item_kits_taxes').' WRITE,'.$this->db->dbprefix('people').' READ,'.$this->db->dbprefix('items').' READ 
    ,'.$this->db->dbprefix('employees_locations').' READ,'.$this->db->dbprefix('locations').' READ, '.$this->db->dbprefix('items_tier_prices').' READ 
    , '.$this->db->dbprefix('location_items_tier_prices').' READ, '.$this->db->dbprefix('items_taxes').' READ, '.$this->db->dbprefix('item_kits').' READ 
    , '.$this->db->dbprefix('location_item_kits').' READ, '.$this->db->dbprefix('item_kit_items').' READ, '.$this->db->dbprefix('employees').' READ , '.$this->db->dbprefix('item_kits_tier_prices').' READ 
    , '.$this->db->dbprefix('location_item_kits_tier_prices').' READ, '.$this->db->dbprefix('location_items_taxes').' READ 
    , '.$this->db->dbprefix('location_item_kits_taxes'). ' READ, '.$this->db->dbprefix('item_kits_taxes'). ' READ'); 


    $this->db->insert('sales',$sales_data); 
    $sale_id = $this->db->insert_id(); 

    //A bunch of mysql other queries to save a sale 


    $this->db->query('UNLOCK TABLES'); 

    $this->db->trans_complete(); 

    if ($this->db->trans_status() === FALSE) 
    { 
     return -1; 
    } 

    return $sale_id; 

} 

답변

2

내가 주로 MySQL은 "LOCK 테이블"이 테이블을 잠그면 전에 활성 트랜잭션를 저지른 사실 beacuse 믿습니다. 아주 명확하게 그리고 완전히 제안 된 솔루션은 autocommit 플래그를 해제하는 것입니다 the MySQL manual page.

에 설명 된대로

사실, 두 가지 작업 (잠금 및 거래) 사이의 상호 작용 (MySQL은 매우 까다로운 보이는 기본적으로 ON, 그래서 일반적으로 발행 된 모든 쿼리는 자동으로 SET autocommit = 0 명령을 issueing에 의해) 실행 후 최선을 다하고 있습니다 :

LOCK 테이블을 사용하고 트랜잭션 TABL와 테이블의 잠금을 해제하려면 올바른 방법 es [..]는 SET autocommit = 0 (START TRANSACTION이 아님)과 LOCK TABLES가있는 트랜잭션을 시작하고 은 트랜잭션을 명시 적으로 커밋 할 때까지 UNLOCK TABLES를 호출하지 않습니다. 당신이 테이블 t1을 작성하고 테이블 T2, 에서 읽을해야하는 경우 예를 들어, 당신은이 작업을 수행 할 수 있습니다

귀하의 코드는 다음과 같이 수 :

$this->db->query("SET autocommit=0"); 
$this->db->query("LOCK TABLES...."); // your query here 
$this->db->query("COMMIT"); 
$this->db->query("UNLOCK TABLES'); 
+0

그냥 후속 질문을. 이 작업을 수행하고 오류가 있어도 트랜잭션이 부분적으로 커밋 된 것 같습니다. 오류가있는 경우 트랜잭션이 커밋되지 않은 위치에서이 작업을 수행 할 수 있습니까? –

관련 문제