2011-12-09 18 views
1

如何确保用户a在用户b访问用户a的数据时手动更新他的某些信息,访问该信息的用户b获取正确的更新信息而不是用户a的陈旧数据。当用户更新时,确保一个用户的select语句对另一个用户是正确的?

我明白事务很好,行级锁定,我只是想确保我做得正确!

当更新我使用的用户一个信息,

$dbc -> beginTransaction(); 
$dbc -> query("SELECT id FROM accounts WHERE id = " . $user['id'] . " FOR UPDATE LIMIT 1"); 
$q = $dbc -> prepare("UPDATE accounts SET name = ?"); 
$q -> execute(array($_POST['name'])); 
$dbc -> commit(); 

使用上面确实该锁的用户一个数据,这样,当用户B得到他的数据,用户一用,

$q = $dbc -> ("SELECT * FROM accounts WHERE id = ?"); 
$q -> execute(array($_GET['id'])); 

他会得到正确的更新数据?或者在获取用户a的用户数据时需要使用事务?

我对所有这些锁和东西都有点困惑,因为你可能知道吗?!?

感谢

+0

行将**写* *只要更新持续,即可锁定。用户B会得到正确的数据吗?取决于他们访问数据的时刻。您必须意识到并发访问意味着“我们时间如此接近以至于看起来像是在同一时间”。 – Alfabravo

+0

是否没有办法执行用户-b的select语句来查看用户-a的信息,该信息只在行未锁定时执行? – cgwebprojects

+0

它不会帮助你,因为你不知道用户A是否已经执行了更新,是吗? – Alfabravo

回答

0

要在网站上,哪里有客户&数据库之间的脱节处理并发,通常的做法是会对每一个可以让你检查后还没有被更新记录的列你最后得到它。

无论是上次更新日期列还是(我的首选项)自动增量版本号(通过触发器实现),您只需检查您的WHERE子句,即获得的值与记录中的值匹配,例如:

UPDATE accounts SET name = ?, lastupdate=sysdate WHERE id = ? AND lastupdate = ? 

如果lastupdate值不匹配,并且因此无法更新记录,则可以假定数据已由其他人更新并相应地处理异常。

这适用于过度更新很少的系统。

我更喜欢使用触发器,因为为您维护了并发值。 (唯一的缺点是,你必须重新查询数据,如果你想重新更新相同的记录,那就是直到MySQL的执行返回的条款)

看到:影响Handling the concurrent request while persisting in oracle database?

相关问题