English 中文(简体)
防止同时坐桌旁浏览
原标题:Preventing simultaneous db table row access

有时,我们支助团队的两家行政正在试图在浏览桌上进行同样的敏感行动(即,修改行价)。 我们需要防止这种情况。 (由于表格是“米斯马”而不可能锁定)

我考虑了几个解决办法:

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;
   }

但情况如下:

  1. 用户需要货币价值从9美元改为10美元

  2. 行政将他的钱改为10美元

  3. 用户明智地花了1美元,因此,他目前的钱再次 9!

  4. 行政将他的钱改为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);

   }

现在,档案的建立是我更喜欢的做法,因为:

  1. 我认为,建立当地档案的速度比使用数据库要快。

  2. 我无需在表格中增加一栏(时段)。

  3. 我可以很容易地修改档案名称,以检查具体的栏目修改,在完成我的时间时,即创建文件“货币_用户{使用}_修改”。

Is that right or is there something I misunderstand?

最佳回答

请具体说明<代码>中的旧价值。 UPDATE operation s WHERE Clause, 然后研究受影响的浏览次数:

Given

id  name          amount
--- ------------- ---------
1   Joe User      10

Thread 1 executes

UPDATE accounts SET amount=9 WHERE id=1 AND amount=10;
=> Query Okay, 1 row(s) affected

2艘船

UPDATE accounts SET amount=9 WHERE id=1 AND amount=10;
=> Query Okay, 0 row(s) affected

除此以外,我很可能在比以前执行排他性规定,首先把任务分派给个别行政机构,以减少浪费时间。

问题回答

在你的案件中,我假定的僵局是最佳办法。 您可使用MySQL locks:。 GET_LOCK, RELEASE_LOCK, IS_FREE_LOCK。 我认为,交易并不能保证,在另一个履行单列数据任务的过程中,行文不会改变。

虽然你的特殊案例与传统意义上的锁定毫无关系。 IMHO, 您需要用相应的全权证书和说明记录您的交易,因此,您的行政部门可以读到这些记录,而不必修改同样的平衡。 洛克比可以保护不受模拟增长的侵扰,但不能防止在洗劫时故意改变。

我认为,数据库的锁定不能满足你首先提到的情况。 但是,我并不认为文件编制比数据库系统更快,两者都没有。 档案制作显然比数据库上的CRUD要重。

因此,我建议对伐木表采取类似做法。

  • Every table has its own primary key (like pid)
  • Record the table name and the pid into log table with timestamp when someone attempt to fiddle a row.
  • Check the log table before running a query.

查阅非行和交易。 它们更适合敏感的变化(即平衡)。

数据库一般较好,因为它们是一个集中的解决办法。 如果你因交通或一般工作负荷而不得不扩大规模,那么将这些档案整理起来并不容易。 除非你不期望任何扩大规模的需要,而且I/O的费率是好的,否则就会ok。

请允许我提及你可能上文提到的两种解决办法。

你可以加上一个“寄出的”账户,加上一个时间序列,这样,如果有人编辑的话,你的申请就会发出警告。

另一种可能的解决办法是检查在填写表格时是否做了任何改动。 这里可以使用最后一批经过编辑的时间。





相关问题
SQL SubQuery getting particular column

I noticed that there were some threads with similar questions, and I did look through them but did not really get a convincing answer. Here s my question: The subquery below returns a Table with 3 ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

php return a specific row from query

Is it possible in php to return a specific row of data from a mysql query? None of the fetch statements that I ve found return a 2 dimensional array to access specific rows. I want to be able to ...

Character Encodings in PHP and MySQL

Our website was developed with a meta tag set to... <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> This works fine for M-dashes and special quotes, etc. However, I ...

Pagination Strategies for Complex (slow) Datasets

What are some of the strategies being used for pagination of data sets that involve complex queries? count(*) takes ~1.5 sec so we don t want to hit the DB for every page view. Currently there are ~...

Averaging a total in mySQL

My table looks like person_id | car_id | miles ------------------------------ 1 | 1 | 100 1 | 2 | 200 2 | 3 | 1000 2 | 4 | 500 I need to ...

热门标签