函数内所有查询的 Codeigniter 事务

Posted

技术标签:

【中文标题】函数内所有查询的 Codeigniter 事务【英文标题】:Codeigniter transaction for all queries within a function 【发布时间】:2017-12-22 19:49:52 【问题描述】:

我有以下这些功能。

public function importExcelFile()
    $file = $_FILES['file']['tmp_name'];

    $data  = extract_excel_data($file);

    $i = 0;
    foreach($data['values'] as $dataValues) 
        $categories = [];
        $brands = [];
        $models = [];

        foreach($dataValues as $value)
            if(array_filter($value)) 

                /* If a row does not contain brand/category/model for the product then fetch the resp. info. from previous row */
                if(empty(trim($value[0]))) 
                    $categories[] = $prev_cat;
                 else 
                    $categories[] = strtoupper(trim($value[0]));
                    $prev_cat = strtoupper(trim($value[0]));
                

                if(empty(trim($value[1]))) 
                    $brands[] = $prev_brand;
                 else 
                    $brands[] = strtoupper(trim($value[1]));
                    $prev_brand = strtoupper(trim($value[1]));
                

                if(empty(trim($value[2]))) 
                    $models[] = $prev_model;
                 else 
                    $models[] = $value[2];
                    $prev_model = $value[2];
                
            
        

        //insert device category
        $this->insert_setups('category', $categories);

        //insert brand
        $this->insert_setups('brand', $brands);

        // Check if branch already exists in the database
        $check_branch = $this->global_model->getDetailByWhere('branch', array('name'=>$data['branch'][$i].' branch'))->result();

        $branch_arr = [];

        //insert branch
        if(empty($check_branch)) 
            $branch_arr = array(
                            'name'          => $data['branch'][$i].' branch',
                            'location'      => $data['branch'][$i],
                            'status'        => 1,
                            'created_by'    => $this->session->userdata('id'),
                            'created_on'    => date('Y-m-d')
                        );

            $this->global_model->insertData('branch', $branch_arr);
        
        $branch_id = $this->global_model->getDetailByWhere('branch', array('name'=>$data['branch'][$i].' branch'))->row()->id;

        $db_device_categories = [];
        $db_brands = [];

        // get categoris, brands
        $db_device_categories = $this->arrangeArray('category', $where =array());
        $db_brands = $this->arrangeArray('brand', $where =array());
        //detail_print($db_brands);

        // insert new models from database
        foreach(array_unique($models) as $model_key=>$model)
            $check_model = $this->global_model->getDetailByWhere('model', array('name'=>$model))->result();
            $insert = [];
            if(empty($check_model))
                $insert = array(
                                    'name' => $model,
                                    'item_type' => 1,
                                    'category_id' => $db_device_categories[$categories[$model_key]],
                                    'brand_id' => $db_brands[$brands[$model_key]],
                                    'created_by' => $this->session->userdata("id"),
                                    'created_on' => date('Y-m-d'),
                                );

                $this->global_model->insertData('model', $insert);
            
        

        $db_device_models = [];
        // get models from database
        $db_device_models = $this->arrangeArray('model', $where = array('item_type'=>1));

        $categoriy_id = [];
        $brand_id = [];
        $model_id = [];
        $opening_stock = [];

        // arrange the exported array with respective id
        foreach($dataValues as $values)
            if(array_filter($values)) 

                if(empty(trim($values[0]))) 
                    $category_id = $prev_cat;
                 else 
                    $category_id = strtoupper(trim($values[0]));
                    $prev_cat = strtoupper(trim($values[0]));
                

                if(empty(trim($values[1]))) 
                    $brand_id = $prev_brand;
                 else 
                    $brand_id = strtoupper(trim($values[1]));
                    $prev_brand = strtoupper(trim($values[1]));
                

                if(empty(trim($values[2]))) 
                    $model_id = $prev_model;
                 else 
                    $model_id = $values[2];
                    $prev_model = $values[2];
                

                $opening_stock[] = array(
                                        'category_id' => $db_device_categories[$category_id],
                                        'brand_id' => $db_brands[$brand_id],
                                        'model_id' => $db_device_models[$model_id],
                                        'imei' => (string)$values[3],
                                        'cost_price' => isset($values[5]) ? $values[5] : 0,
                                        'selling_price' => isset($values[6]) ? $values[6] : 0
                                    );
            
        

        $group_by_model = [];

        // group the array by model_id
        foreach(array_unique($models) as $model1)
            $where = $db_device_models[$model1];

            $group_by_model[] = array_filter($opening_stock, function($elements) use ($where)
                return $elements["model_id"] == $where;
            );
        

        if(!$this->purchase_model->insertOpeningStock($group_by_model, $branch_id))
            $this->session->set_flashdata('error', 'Opening stock of devices insertion failed.');
            redirect('purchase/uploadExcelFile');
        
        $i++;
    
    $this->session->set_flashdata('success', 'Opening stock of devices added successfully.');
    redirect('purchase/uploadExcelFile');


private function arrangeArray($table, $where)
    $list = $this->global_model->getDetailByWhere($table, $where)->result_array();
    foreach($list as $item)
        $name = $item['name'];
        $arranged_list[$name] = $item['id'];
    
    return !empty($arranged_list) ? $arranged_list : NULL;



private function insert_setups($table_name, $setups)
    foreach(array_unique($setups) as $value)
        $check_setup = $this->global_model->getDetailByWhere($table_name, array('name'=>$value))->result();
        if(empty($check_setup))
            $insert = array(
                                'name' => $value,
                                'created_by' => $this->session->userdata("id"),
                                'created_on' => date('Y-m-d'),
                            );
            $this->global_model->insertData($table_name, $insert);
        
    

这个函数的作用是,它从上传的excel文件中提取数据,并相应地将数据插入到各个表中。现在您可以看到,importExcelFile() 方法内的不同位置运行了多个查询。所以我的问题是,我如何使用 codeigniter 事务以使该函数内的所有查询都以原子方式执行。如果任何一个查询失败,所有其他查询的工作都会回滚。另外,这段代码是否被认为是干净的?

附:如果我的最后一个问题在这里不恰当,我很抱歉。

【问题讨论】:

【参考方案1】:

这可能对您有所帮助。 transactions in codeigniter

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

【讨论】:

以上是关于函数内所有查询的 Codeigniter 事务的主要内容,如果未能解决你的问题,请参考以下文章

Codeigniter 查询更新所有行而不是 1

使用 CodeIgniter 事务?

CodeIgniter 事务 - trans_status 和 trans_complete 返回 true 但没有提交

如何获取 Codeigniter 中模型之间事务中关系的最后一个 ID?

Codeigniter - 在查询生成器的“来自”函数中停止转义

更新查询增量字段加 1 个 codeigniter 函数