Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何禁止两个用户在使用MySQL的web应用程序中编辑相同的数据(如果可能,使用CodeIgniter)_Mysql_Codeigniter_Transactions_Locking_Mariadb - Fatal编程技术网

如何禁止两个用户在使用MySQL的web应用程序中编辑相同的数据(如果可能,使用CodeIgniter)

如何禁止两个用户在使用MySQL的web应用程序中编辑相同的数据(如果可能,使用CodeIgniter),mysql,codeigniter,transactions,locking,mariadb,Mysql,Codeigniter,Transactions,Locking,Mariadb,我在我的开发环境中使用CodeIgniter 3和MariaDB 5.0(但在prod环境中使用MySQL 5.6) 我创建了一个web应用程序,并实现了一个验证链来接受用户请求 例如: User A asked for something The manager validate The deputy validate The commission validate The accounting department validate The request is accepted 这些验证

我在我的开发环境中使用CodeIgniter 3和MariaDB 5.0(但在prod环境中使用MySQL 5.6)

我创建了一个web应用程序,并实现了一个验证链来接受用户请求

例如:

User A asked for something
The manager validate
The deputy validate
The commission validate
The accounting department validate
The request is accepted
这些验证在数据库中的几个表中注册

我使用SQL事务使用 CodeIgniter的功能和积垢模型,示例:

$this->db->trans_start();
$this->my_model->create($data);
$another_data = $this->second_model->read($second_data);
$this->another_model->create($another_data);
$this->db->trans_complete();
但现在,我必须为总经理执行一项新规定。他有能力随时验证,这种验证打破了验证链,因为它算作每个人都验证过

这种情况可能是一个例子:

User A asked for something
The manager validate
The general manager validate
The request is accepted
我不知道如何实现这一点,因为我意识到两个用户(例如总经理和副总经理)可以咨询同一个请求,一个拒绝,另一个验证,并且数据不再一致

这笔交易够好吗?比如:

// User A asked for something
// The manager validate
// The deputy consult the request
// The manager consult the request
// The deputy validate:

    $this->db->trans_start();

    // check if already validated by the general manager
    if ($this->model->read($data)) {
        $this->db->trans_complete();
        // redirection to a warning page
    }
    else {
        $this->my_model->create($my_data);
    }
    $this->db->trans_complete();

    if ($this->db->trans_status() === FALSE)
        // redirection to another warning page

// The general manager wants to refuse at the same time but the deputy's transaction started first, so he's redirected to a warning page

    $this->db->trans_start();

    // check if already validated by anyone
    if ($this->model->read($data)) {
        $this->db->trans_complete();
        // redirection to a warning page
    }
    else {
        $this->my_model->create($my_data);
    }
    $this->db->trans_complete();

    if ($this->db->trans_status() === FALSE)
        // redirection to another warning page

// The validation chain continues after the deputy's validation
我考虑使用锁表来禁止用户在其他人咨询相同请求时访问验证页面。但是
TRANSACTION
LOCK TABLE
很难实现,因为它可以触发隐式提交,而我还没有足够的能力来正确实现这一点

我读过关于
START TRANSACTION read WRITE
的文章,这可能是一个更好的解决方案,但我并不完全理解这一点,我也不知道如何正确实现这一点


有人能帮我实施好的策略吗?如果可能的话,还有在需要时使用这些SQL函数的方法吗?

我找到了解决方案,我在查询后使用了
进行更新,如下所示:

// the query for my results
private model_function_for_query() {
    $this->db->select('my_select');
    $this->db->from('my_table');
    $this->db->where('my_where_clause');

    return $this->db->get_compiled_select();
}

// the function to apply the FOR UPDATE on the query
public model_function() {
    $query = $this->model_function_for_query();
    $result = $this->db->query($query.' FOR UPDATE');

    return $result->row();
}
在我的控制器中:

// start the transaction
$this->db->trans_start();

// do the query, locking tables
$data = $this->my_model->model_function();

// check if the data has not changed
...

// if not, do the data treatment, else redirect to the warning page
...

// close the transaction
$this->db->trans_complete();

// check if the transaction failed, and do the stuff
if ($this->db->trans_status() === FALSE)
    ...
else
    ...

我找到了解决方案,在查询之后,我使用
进行更新
,如下所示:

// the query for my results
private model_function_for_query() {
    $this->db->select('my_select');
    $this->db->from('my_table');
    $this->db->where('my_where_clause');

    return $this->db->get_compiled_select();
}

// the function to apply the FOR UPDATE on the query
public model_function() {
    $query = $this->model_function_for_query();
    $result = $this->db->query($query.' FOR UPDATE');

    return $result->row();
}
在我的控制器中:

// start the transaction
$this->db->trans_start();

// do the query, locking tables
$data = $this->my_model->model_function();

// check if the data has not changed
...

// if not, do the data treatment, else redirect to the warning page
...

// close the transaction
$this->db->trans_complete();

// check if the transaction failed, and do the stuff
if ($this->db->trans_status() === FALSE)
    ...
else
    ...