【问题标题】:Does this suffice, or do I have race conditions?这是否足够,或者我有竞争条件?
【发布时间】:2011-04-03 05:50:41
【问题描述】:

我正在为网络编写一种策略类多用户游戏。它有一个游戏场(X x Y 方格),我计划将其序列化并存储在 MySQL(innodb)数据库中的 BLOB 中,每个正在进行的游戏一行。

我现在试图找出一个好方法,让数据库随着比赛场地的任何变化而更新,同时找到一个方便的解决方案来处理在加载之间的时间范围内比赛场地发生的事情页面并实际采取行动。
我不使用 AJAX。

每局游戏最多有 20 名玩家,每个玩家在 24 小时内走 1 到 10 步,所以这是一款“慢”游戏。

我的计划(到目前为止)还为 blob 旁边的 playfield 存储一种校验和,并在尝试更改 playfield 之前将数据库状态与加载的状态进行比较。

我担心的是如何防止竞争条件。
是否足够:

  1. 开始交易。
  2. 从表中加载游戏场
  3. 如果校验和不同 - 回滚并更新用户视图
  4. 如果校验和未更改 - 更新表并提交更改

BEGIN TRANSACTION 是否足以阻止比赛,还是我需要在第 2 步中做更多的事情来表明我更新表格的意图?

感谢所有建议。

【问题讨论】:

    标签: mysql web-applications rdbms race-condition multi-user


    【解决方案1】:

    如果您在从数据库加载游戏场时使用SELECT ... FOR UPDATE,它将阻止其他选择,直到您提交或回滚事务。

    【讨论】:

    • 太棒了。我的“算法”看起来也很正常吗?我的意思是,我是否保证同时执行上述 2 个步骤(使用FOR UPDATE)的两个(或任意数量)线程将被序列化,因此一次只有 1 个进程可以访问相关行?
    • 是的,一旦一个线程在该行上发出 SELECT FOR UPDATE,所有其他线程将停止其 SELECT FOR UPDATE 直到该事务完成。然后通过的下一个线程将读取更新的行。
    【解决方案2】:

    没有。您需要为需要防止冲突更新的表发出 LOCK TABLES 命令。这看起来像......

    LOCK TABLE my_table WRITE;
    

    更多细节可以在这里找到...http://dev.mysql.com/doc/refman/5.1/en/lock-tables.html

    之后别忘了解锁它们!

    【讨论】:

    • LOCK TABLE 会起作用,但比必要的更严厉。最好只锁定您需要的行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 2011-09-16
    • 1970-01-01
    • 2018-06-03
    相关资源
    最近更新 更多