如何禁止两个用户在使用MySQL的web应用程序中编辑相同的数据(如果可能,使用CodeIgniter)
我在我的开发环境中使用CodeIgniter 3和MariaDB 5.0(但在prod环境中使用MySQL 5.6) 我创建了一个web应用程序,并实现了一个验证链来接受用户请求 例如:如何禁止两个用户在使用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 这些验证
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
...