2个用户同时更新记录

时间:2012-06-19 11:21:44

标签: php mysql

我想知道在以下假设情况下会发生什么。假设两位老师给同一个学生提供完全相同的课程,他们都希望更新学生,鲍勃的成绩。鲍勃目前的平均水平是60%,老师1希望通过测试更新他的平均值,他得到70%,老师2想要通过测试更新他的平均值,他得分为40%。

因此,在两位教师同时点击更新按钮的情况下,有一百万到一百万的机会,恰好同时准确到达瞬间,将会发生什么?它会给出错误信息吗,php或mysql神奇地排队更新,只会是第一个得分更新bob的平均值而第二个用户得到错误吗?

编辑:我担心的是第二个用户必须在第一个用户编辑值后获取值,我正在考虑获取记录然后在php中进行计算然后再次更新记录,但在这种情况下如何才能我确保第二个用户获取的值为65%而不是60%,这可以通过事务完成吗?

5 个答案:

答案 0 :(得分:3)

他们不能同时运行动作,总会有一个小的差异,因为机器在物理上不可能同时写入相同的信息。可能是微秒或更小,但差异就在那里。

通常的解决方案之一是在WHERE子句中添加类似的数据,并检查是否已完成更新:

UPDATE students SET `avg` = '70' WHERE id=<some-id> AND `avg` = '60';

然而,像 averages 这样的东西通常最好不要这样更新:有一个单独的学生分数表,并自己计算每个学生的平均记录(你仍然可以'缓存如果你愿意,可以在学生表中

答案 1 :(得分:2)

两者都将通过,最后一个要处理的将是新值。由于数据库系统的一致性保证,您不会获得损坏的数据,但由于这是一个计算值,您可能会得到错误的数据。

我怀疑这个平均值是基于其他表中数据的计算值。如果是这种情况,请在一次交易中完成所有工作。将新的测试分数添加到表中,让数据库计算平均值并将结果直接插入到第二个表中。这样,结果将保证正确事务将失败。这需要具有事务支持的存储引擎(例如,InnoDB)。

答案 2 :(得分:1)

数据库将按顺序更新行。其中一个查询将首先运行,锁定行(或有时是表 - 取决于查询),下一个查询将排队,直到第一个查询完成。

答案 3 :(得分:1)

如果操作是原子的,你不会遇到任何麻烦。你的INSERT是。两个INSERT都将被执行。

谨防非原子操作!

这是交易进入的地方:http://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_transaction

答案 4 :(得分:1)

悲观锁定和交易只是这里故事的一半。数据库将取出行锁,但这只能确保尝试修改同一行的任何人必须等到当前事务完成。我想要阻止的案例是:

  1. 教师a查看作业并看不到成绩。
  2. 教师b查看作业并且没有成绩。
  3. 老师a指定了70年级。
  4. 老师b指定40年级。
  5. b很可能并不意味着覆盖a。您最好的保护是某种形式的乐观锁定。当两个人同时进行编辑时,你会在wiki中看到这个。后一个提交者必须确认编辑,因为它可能会意外地反转先前提交者的更改。在评分的情况下,您可以在where子句中添加显示给用户的旧等级,然后断言更新更改了一行。

    UPDATE GRADES SET SCORE=70 WHERE NAME='Jim' AND SCORE=0;