PHP / MYSQL事务生成两个相同的主键

时间:2016-11-13 12:49:32

标签: php mysql pdo

我有一个用作Web服务的函数。代码如下所示。

public function create_order() {
       try{
            $this->db->trans_begin();
            $this->form_validation->set_rules($this->form_validation_array->get_app_rules('authenticate'));
            $this->form_validation->set_rules("table_id","Table_id","required");
           // $this->form_validation->set_rules("item[]","Items","required");
            if ($this->form_validation->run() == true) {
                $credential = array(
                    "restaurant_id" => $this->input->post("restaurant_id"),
                    "app_user_id" => $this->input->post("app_user_id"),
                    "app_id" => $this->input->post("app_id"),
                    "app_secret_id" => $this->input->post("app_secret")
                );
                $check = $this->authenticate_app_user($credential);
                if($check){
                   $order_data = array(
                        "user_id" => $credential['restaurant_id'],
                        "table_id" => $this->input->post("table_id"),
                        "created_by" => $credential['app_user_id'],
                        "created_date" => current_timestamp(),
                        'comments'=> ($this->input->post('comment')) ? $this->input->post('comment') : NULL, 
                        'status'=>1,
                    );
                    $order_id = $this->ws_details_model->current_order_id($order_data);
                    log_message('error','order_id_while_inserting '.print_r($order_id,true));
                    if(!$order_id) {
                       $order_data['unique_order_id'] = $this->common_function->unique_no('order');
                       $this->common_details_model->complete_existing_order($order_data);
                       $order = $this->ws_details_model->create_order($order_data);
                    } else {
                       $order_data['unique_order_id'] = $order_id->unique_order_id;
                       $order = $order_id->id;
                    }

                    if($order){
                       //$item_data = json_decode($this->input->post("item"),true);
                       $item_data = $this->input->post("item");
                       log_message('error','===============order id : '.$order.' is started====================\n');
                       log_message('error',cook_log_message('order_array_without_process',$item_data));
                        if(is_array($item_data)) {
                            $order_item_data = array();
                            $j=0;
                            foreach ($item_data as $i){
                                $item_details = $this->ws_details_model->get_item_details($i['item_id']);
                                $toppings = $toppings_price = $varient = $varient_price = $topping_text = $varient_text = '';
                                 $topping_price = 0.00;
                                if(isset($i['item_topping'])) {
                                   $topping_details = $this->ws_details_model->get_toppings_details(explode(',',$i['item_topping']));
                                   if(!empty($topping_details)) {
                                      foreach($topping_details as $topping) {
                                         if($topping->is_t_v == 1) {
                                            $price = !empty($topping->price) ? $topping->price : '0';
                                            $toppings.= $topping->id.'|'.$topping->title.'|'.$price.',';
                                            $topping_text.= $topping->title.',';
                                            //$toppings_price.= (!empty($topping->price) ? $topping->price : '0').',';
                                         } else {
                                            $price = !empty($topping->price) ? $topping->price : '0';
                                            $varient.= $topping->id.'|'.$topping->title.'|'.$price.',';
                                            $varient_text.= $topping->title.',';
                                            //$varient_price.= (!empty($topping->price) ? $topping->price : '0').',';
                                         }
                                         $topping_price = $topping_price + $topping->price;
                                      }
                                   }
                                }
                                if($i['item_id']){
                                    $order_item_data[$j] = array(
                                        "order_id" => $order,
                                        "item_id" => $i['item_id'],
                                        "item_name" => $item_details['title'],
                                        "category_name" => $item_details['category_name'],
                                        "item_size" => $i['item_size'],
                                        "item_quantity" => $i['item_quantity'],
                                        "created_by" => $credential['app_user_id'],
                                        "created_date" => current_timestamp(),
                                        'comments'=> ($this->input->post('comment')) ? $this->input->post('comment') : NULL, 
                                        'status'=>1,
                                        "toppings"=>(!empty($toppings)) ? trim($toppings,',') : NULL,
                                        "toppings_text"=>(!empty($topping_text)) ? trim($topping_text,',') : NULL,
                                        "toppings_price"=>NULL,
                                        "varient"=>(!empty($varient)) ? trim($varient,',') : NULL,
                                        "varient_text"=>(!empty($varient_text)) ? trim($varient_text,',') : NULL,
                                        "varient_price"=>NULL,
                                    );
                                    if($i['item_size'] == 1) {
                                       $order_item_data[$j]['item_price'] = $item_details['small_price'];
                                    } elseif($i['item_size'] == 2) {
                                       $order_item_data[$j]['item_price'] = $item_details['medium_price'];
                                    } elseif($i['item_size'] == 3) {
                                       $order_item_data[$j]['item_price'] = $item_details['large_price'];
                                    } else {
                                       $order_item_data[$j]['item_price'] = $item_details['price'];
                                    }
                                    $order_item_data[$j]['final_price'] = ($order_item_data[$j]['item_quantity'] * $order_item_data[$j]['item_price']) + ($order_item_data[$j]['item_quantity'] * $topping_price);
                                    $j++;
                                }
                            }
                            log_message('error',cook_log_message('process_order_array_before_insert',$order_item_data));
                            $order_item = $this->ws_details_model->insert_order_item($order_item_data);
                            $table_data = array(
                               'status'=>3,
                               'updated_by'=>$credential['app_user_id'],
                               'updated_date'=>  current_timestamp()
                            );
                            $this->ws_details_model->change_table_status($order_data['table_id'],$table_data);
                            if ($this->db->trans_status() === FALSE)
                            {
                                $this->db->trans_rollback();
                                $data = array('result' => 'error', 'msg' => "Something went wrong!!! Please try again.");
                            }
                            else
                            {
                                $this->db->trans_commit();
                                log_message('error','===============order id : '.$order.' is end====================\n');
                                $this->publish($credential['restaurant_id'],'inhouse',array('order_id'=>$order,'order_type'=>'inhouse'));
                                $data = array('result' => 'success', 'msg' => 'Order has been placed successfully','order_id'=>$order,'unique_order_id'=>$order_data['unique_order_id']);
                            }
                        } else {
                           $data = array('result' =>'error', 'msg' => "Item data is not in proper format");
                           $this->db->trans_rollback();
                        }
                    } else {
                        $data = array('result' => 'error', 'msg' => "Something went wrong!!! Please try again.");
                         $this->db->trans_rollback();
                    }
                } else {
                    $data = array('result' => 'error', 'msg' => "You are not authenticated user");
                    $this->db->trans_rollback();
                }
            }
            else {
               $data = array('result' => 'error', 'msg' => preg_replace("/[\n\r]/", "", strip_tags(validation_errors())));
               $this->db->trans_rollback();
            }
            echo json_encode($data);
       } catch (Exception $e) {
          $this->db->trans_rollback();
          log_message('error',cook_log_message('app_create_order_error',$e->getMessage()));
       }
    }

现在问题就出现了。

  1. 当此函数调用时,它会自动插入一些不在order_item_data数组中的行。我知道它有点奇怪,但如果你可以查看下面的截图,你会明白我在说什么。 enter image description here
  2. 为了追溯这个问题,我已经将日志系统与我的功能放在一起了。当我检查日志时,我发现相同的主键已生成两次。 下面是日志

    ERROR - 2016-11-12 21:49:07 --> ===============order id : 5091 is started====================\n
    ERROR - 2016-11-12 21:49:07 --> 2016-11-12 21:49:07 :  : Order array without process  : order_array_without_process : Array
    (
        [0] => Array
            (
                [item_id] => 40
                [item_size] => 0
                [item_quantity] => 1
                [item_topping] => 79
            )
    
    )
    ERROR - 2016-11-12 21:49:07 --> ===============order id : 5091 is end====================\n
    
    ERROR - 2016-11-12 22:15:08 --> ===============order id : 5091 is started====================\n
    ERROR - 2016-11-12 22:15:08 --> 2016-11-12 22:15:08 :  : Order array without process  : order_array_without_process : Array
    (
        [0] => Array
            (
                [item_id] => 65
                [item_size] => 0
                [item_quantity] => 1
            )
    
        [1] => Array
            (
                [item_id] => 64
                [item_size] => 0
                [item_quantity] => 1
            )
    
    )
    ERROR - 2016-11-12 22:15:08 --> ===============order id : 5091 is end====================\n
    

    在上面的日志中你可以看到 order_id 5091 这是主要的关键,它生成了两次,而如果可以检查错误 - 日志时间比两者都有不同的时间比怎么可能?

    以下是表格结构。

    1。订购表

    CREATE TABLE `m_order` (
     `id` int(11) NOT NULL AUTO_INCREMENT,
     `user_id` int(11) NOT NULL COMMENT 'belongs to m_users table',
     `table_id` int(11) DEFAULT NULL COMMENT 'belongs to m_table',
     `unique_order_id` varchar(100) DEFAULT NULL,
     `order_type` int(1) NOT NULL DEFAULT '1' COMMENT '1=table_order,2=take_away',
     `payment_by` int(11) NOT NULL DEFAULT '0' COMMENT '1=cash,2=card',
     `order_from` int(11) DEFAULT '1' COMMENT '1=web,2=app',
     `device_id` text COMMENT 'device id from where order placed',
     `device_name` varchar(254) DEFAULT NULL,
     `delivery_taken_by` int(11) DEFAULT NULL COMMENT 'belongs to m_staff tables ',
     `comments` text,
     `ip_address` varchar(40) DEFAULT NULL,
     `created_by` int(11) NOT NULL,
     `updated_by` int(11) DEFAULT NULL,
     `created_date` int(20) NOT NULL,
     `updated_date` int(20) DEFAULT NULL,
     `status` int(1) NOT NULL DEFAULT '1' COMMENT '1=current order,2=completed,3=order cancelled,4=out for delivery',
     PRIMARY KEY (`id`),
     KEY `user_id` (`user_id`),
     KEY `table_id` (`table_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=180 DEFAULT CHARSET=utf8
    

    2。订单项目表格结构

    CREATE TABLE `m_order_items` (
     `id` int(11) NOT NULL AUTO_INCREMENT,
     `order_id` int(11) NOT NULL,
     `item_id` int(11) NOT NULL,
     `category_name` varchar(200) DEFAULT NULL,
     `item_name` varchar(100) NOT NULL,
     `item_size` varchar(100) NOT NULL COMMENT 'small,medium,large',
     `item_price` float(12,2) NOT NULL,
     `item_quantity` float NOT NULL DEFAULT '1',
     `item_unit` varchar(255) DEFAULT NULL,
     `toppings` varchar(250) DEFAULT NULL,
     `toppings_text` varchar(255) DEFAULT NULL,
     `toppings_price` varchar(250) DEFAULT NULL,
     `varient` varchar(250) DEFAULT NULL,
     `varient_text` varchar(255) DEFAULT NULL,
     `varient_price` varchar(250) DEFAULT NULL,
     `final_price` float(12,2) DEFAULT NULL,
     `comments` text,
     `ip_address` varchar(40) DEFAULT NULL,
     `created_by` int(11) NOT NULL,
     `updated_by` int(11) DEFAULT NULL,
     `created_date` int(20) NOT NULL,
     `updated_date` int(20) DEFAULT NULL,
     `is_printed` int(1) NOT NULL DEFAULT '0' COMMENT '1=printed,0=not yet printed',
     `status` int(1) NOT NULL DEFAULT '1' COMMENT '1=active,2=completed,3=cancelled,4=after serve return,5=deleted',
     PRIMARY KEY (`id`),
     KEY `order_id` (`order_id`),
     CONSTRAINT `m_order_items_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `m_order` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB AUTO_INCREMENT=430 DEFAULT CHARSET=utf8
    

    所以,如果有人能够理解这个问题,请帮助解决这个问题。我应该在代码中做些什么更改,这样我的数组就不会有额外的项目,而且它的主要内容与发布的数组值相同。

    提前致谢。

0 个答案:

没有答案