有时,我们支助团队的两家行政正在试图在浏览桌上进行同样的敏感行动(即,修改行价)。 我们需要防止这种情况。 (由于表格是“米斯马”而不可能锁定)
我考虑了几个解决办法:
setting the old value in the form and comparing it with the current one on submit
<input name="money"><input type="hidden" name="old_money" value="10">
之后更新:
$currentmoney=value_from_query("select money from mytable","money");
if($currentmoney!=$_REQUEST["old_money"]){
return "value changed to $currentmoney while you were editing it, are you sure you still want to change it?!??!?!?!?";
}
else{
mysql_query("update everyonesmoney set money= ".intval($_REQUEST["money"])." where user= $user_id ");
return true;
}
但情况如下:
用户需要货币价值从9美元改为10美元
行政将他的钱改为10美元
用户明智地花了1美元,因此,他目前的钱再次 9!
行政将他的钱改为10美元,没有警告。
creating timestamp (updated_at column) setting in the row
并且与解决办法相同 1. 这比简单数据比较有利。 我们可以肯定的是,如果数据发生变化,我们就拿不出数据。 不利情况——除非我们与解决办法1相结合,否则我们无法追踪哪一栏被准确改动。
<input type="hidden" name="formtimestamp" value="<? echo time();?>">
之后更新:
$query_add = ($overriden ? "" : " and updated_at> ".securevalue($_REQUEST["formtimestamp"])." ");
if(mysql_affected_rows(mysql_query("update everyonesmoney set money= ".intval($_REQUEST["money"])." , updated_at=NOW() where user= $user_id ".$query_add))==0){
return "some values were changed by someone else while you were editing it, are you sure you still want to change it?!??!?!?!?";
}
else{
return true;
}
creating the temporary 0-length file with object/action-specific name
Creating/locking it during the update, and checking for its existence/datestamp before update.
更新前:
$myfname="/tmp/user{$user_id}EDITMONEY.tmp";
$timedifference=((time()-filectime($myfname)); //in seconds
if(file_exists($myfname) and ($timedifference<60) and (!$overriden)){ // a minute difference
$currentmoney=value_from_query("select money from mytable","money");
return "money were edited by someone else $timedifference seconds ago and set to {$currentmoney}, are you sure you still want to change it?!??!?!?!?";
}else{
$fp = fopen("/tmp/user".intval($_REQUEST["user_id"])."EDITMONEY.tmp", "r+");
if (flock($fp, LOCK_EX)) { // do an exclusive lock
mysql_query("update everyonesmoney set money= ".intval($_REQUEST["money"])." where user= $user_id ")
flock($fp, LOCK_UN); // release the lock
return true;
} else {
return "Couldn t get the lock, it s possible that someone tried to execute query simultaneously!";
}
fclose($fp);
}
现在,档案的建立是我更喜欢的做法,因为:
我认为,建立当地档案的速度比使用数据库要快。
我无需在表格中增加一栏(时段)。
我可以很容易地修改档案名称,以检查具体的栏目修改,在完成我的时间时,即创建文件“货币_用户{使用}_修改”。
Is that right or is there something I misunderstand?