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

How to forbid 2 users to edit the same data in a web application using MySQL (with CodeIgniter if possible)

我在开发环境中使用 CodeIgniter 3 和 MariaDB 5.0(但在生产环境中使用 MySQL 5.6)。

我创建了一个网络应用程序,并实施了一个验证链来接受用户请求。

例如:

User A asked for something
The manager validate
The deputy validate
The commission validate
The accounting department validate
The request is accepted

这些验证记录在数据库中的多个表中。

我使用 SQL 事务来 update/insert 正确地处理数据 CodeIgniter的函数和CRUD模型,例子:

$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

我不知道怎么实现,因为我发现2个用户(比如总经理和副手)可以咨询同一个请求,一个拒绝,另一个验证,数据不一致没有了。

交易是否足够好?喜欢:

// 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

我想到了 LOCK TABLE 来禁止用户访问验证页面,而其他人正在咨询相同的请求。但是 TRANSACTIONLOCK TABLE 很难实现,因为它会触发隐式提交,而且我还没有足够的时间来做这件事。

我读到 START TRANSACTION READ WRITE 这可能是一个更好的解决方案,但我并没有完全理解,而且我不确定如何正确实施它。

任何人都可以帮助我实施好的策略,如果可能的话,如果需要,可以使用这些 SQL 函数的方法吗?

我找到了解决方案,我在查询后使用了 FOR UPDATE,这里是:

// 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
    ...