为不同的请求生成相同的序列号

时间:2019-07-14 07:37:51

标签: php mysql cakephp

我正在将序列号插入总是递增一个的表中,但是当同时有多个请求时,它将为不同的请求插入相同的序列号。我正在使用mysql数据库。

我知道我在代码中太早获取最大序列号,并且如果请求是在同一时间发送的,那么它将为两个都获取相同的序列号。完成所有工作后更新序列号是个好主意吗?如果同时为新请求插入一条记录并更新前一个的序列号怎么办?

public function add(){
    $session          = $this->request->session();

    $company_id       = $session->read('Admin.company_id');
    $emp_id           = $session->read('Admin.emp_id');
    $user_email_id           = $session->read('Admin.email_id');
    $employee_name           = $session->read('Admin.employee_name');

    $conn = ConnectionManager::get('default');

    if ($this->request->is('post')) {

        try{

                $conn->begin();   
                $department = $this->request->data['department'];
                $data = $this->request->data;

                if(!array_key_exists('is_requisition_for_contractor', $data)){
                    $is_requisition_for_contractor = 0;
                } else {
                    $is_requisition_for_contractor = $data['is_requisition_for_contractor'];
                }

                if(!array_key_exists('is_requisition_for_employee', $data)){
                    $is_requisition_for_employee = 0;
                } else {
                    $is_requisition_for_employee = $data['is_requisition_for_employee'];
                }

                if(!array_key_exists('is_boulder_requisition', $data)){

                    $is_requisition_for_boulder = 0;
                } else {
                    if($data['is_boulder_requisition'] == ''){
                        $is_requisition_for_boulder = 0;
                    } else {
                        $is_requisition_for_boulder = $data['is_boulder_requisition'];
                    }
                }
                $is_requisition_for_plant = 0;
                if(!array_key_exists('is_plant_requisition', $data)){

                    $is_requisition_for_plant = 0;
                } else {
                    if($data['is_plant_requisition'] == ''){
                        $is_requisition_for_plant = 0;
                    } else {
                        $is_requisition_for_plant = $data['is_plant_requisition'];
                    }
                }

                if(array_key_exists("files",$this->request->data)) {
                    $files      = $this->request->data['files'];

                    if (count($files)) {
                        $files_uploading_response = $this->uploadMultipleFiles($files, 'files/requisitions/');
                    }
                }
                $last_material_insert_id = '';
                if($this->request->data('material_id')[0] == ''){
                    if($this->request->data('department') == 1){
                        $type = 1;
                    } elseif($this->request->data('department') == 3){
                        $type = 3;
                    } elseif($this->request->data('department') == 2){
                        $type = 2;
                    }
                    if($this->request->data('department') == 1 || $this->request->data('department') == 3){
                        $conn->execute("INSERT INTO material (material_name, material_type_id, company_id, status, is_approved_by_admin) VALUES (?,?,?,?,?)",[$this->request->data('material_name'), $type, $company_id, 1,0]);
                        $last_material_insert_id = $conn->execute("SELECT LAST_INSERT_ID() AS last_id")->fetchAll('assoc');
                    } elseif($this->request->data('department') == 2) {

                        //todo for unapproved material
                        $conn->execute("INSERT INTO material (part_no, material_type_id, company_id, status, is_approved_by_admin,unique_category_id) VALUES (?,?,?,?,?,?)",[$this->request->data('part_no')[0], $type, $company_id, 1,0,$this->request->data('unique_category_id')[0]]);
                        $last_material_insert_id = $conn->execute("SELECT LAST_INSERT_ID() AS last_id")->fetchAll('assoc');
                    }

                }
                // here i am fatching max serial number from table
                $requistion_number          = $conn->execute("SELECT IF(MAX(requisition_no) IS NULL, 0,MAX(requisition_no))  AS requisition_no FROM requisition WHERE site_id = ?",[$this->request->data('site_id')])->fetchAll('assoc');
                $Requisition                = TableRegistry::get('requisition');
                $requisition                = $Requisition->newEntity();
                $requisition->registered_on = $this->request->data['date'];
                $requisition->department_id = $this->request->data('department');
                $requisition->site_id = $this->request->data('site_id');
                $requisition->issues_to_id = $this->request->data['prepared_by_id'];
                $requisition->prepared_by_id = $this->request->data['prepared_by_id'];
                $requisition->approved_by_id = $this->request->data['hod_id'];
                $requisition->hod_id         = $this->request->data['hod_id'];
                $requisition->is_diesel_requisition_for_employee = $is_requisition_for_employee;
                $requisition->is_diesel_requisition_for_contractor = $is_requisition_for_contractor;
                $requisition->is_requisition_for_boulder         = $is_requisition_for_boulder;
                $requisition->is_requisition_for_plant = $is_requisition_for_plant;
                if(array_key_exists('for_tanker_stock', $this->request->data))    {
                    $requisition->for_tanker_stock         = 1;
                }
                if($last_material_insert_id != ''){
                    $requisition->is_material_approved_by_admin = 0;
                }
                $requisition->status         = 1;
                $site_id                     = $this->request->data['site_id'];
                $requisition->requisition_no = $requistion_number[0]['requisition_no'] + 1;
                $requistionnumber = $requistion_number[0]['requisition_no'] + 1;


                $saveRequsition = $Requisition->save($requisition);
                $conn->commit();
}

我期望每个请求输出不同的序列号。任何优化方法都可以做到这一点。预先感谢。

2 个答案:

答案 0 :(得分:0)

您当前要做的是首先获得旧的申请编号,如下所示:

$requistion_number = $conn->execute("SELECT IF(MAX(requisition_no) IS NULL, 0,MAX(requisition_no)) AS requisition_no 
                                     FROM requisition WHERE site_id = ?",[$this->request->data('site_id')])->fetchAll('assoc');

然后增加它,然后再保存并提交。

我的建议是在保存并提交请购单之前根本不设置$requistion_number ,而是在之后确定$requistion_number

您现在想知道如何?

好吧,您需要计算该申请所针对的站点的表中的申请行总数,然后添加一个,如下所示:

$last_requisition_id = $conn->execute("SELECT LAST_INSERT_ID() AS last_id")->fetchAll('assoc');
$site_id = $this->request->data('site_id');
$requisition_number = $conn->execute("SELECT COUNT(*) AS requisitionsCount 
                                      FROM requisition
                                      WHERE <primary_key> <= ? AND
                                            site_id = ?",
                                      [$last_requisition_id, $site_id]) + 1;
$conn->execute("UPDATE requisition 
                SET requisition_no = ?
                WHERE <primary_key> <= ?",
               [$requisition_number, $last_requisition_id]);

我知道此代码无法正常工作。 $requisition_number可能包含一个以requisitionsCount作为值的数组,但是您可以对此进行纠正。

由于使用的是数据库表中已经存在的数据,因此不会冒两行将获得相同的$requisition_number的风险。 这里的假设是请购单不会被删除。

答案 1 :(得分:0)

好吧,采用相同的策略,在插入行之后设置$requisition_number(请参阅我的其他答案),但是使用与用于确定新申请编号相同的方法的单个查询:< / p>

$conn->execute("UPDATE requisition 
                SET requisition_no = (SELECT IF(MAX(requisition_no) IS NULL, 0,MAX(requisition_no)) AS requisition_no FROM requisition WHERE site_id = ?) + 1",
               [$this->request->data('site_id')]);

这里的想法是,单个查询将在一个步骤中执行,而不会受到其他类似查询的干扰。