网页游戏并发控制

时间:2010-11-09 15:37:53

标签: php database web-applications concurrency

还有其他一些关于并发的SO问题,但它们并没有完全解决我的问题。

所以,让我们说我有一个游戏,用户互相交流,战斗等等。在任何给定时间,玩家都可能参与与其他玩家的多次互动,所有玩家都可以看到事件发生。当其中任何一个玩家访问该网站时,它需要更新所涉及的任何数据并向用户显示。

示例情况:玩家A正在与玩家B战斗,并且在此战斗中每隔几分钟发生一次事件。与此同时,玩家A也在与玩家C进行互动。幸运的是,这两种互动的事件接下来应该在同一秒内完成。

当那一秒到来时,再次由于运气不好,玩家B和玩家C同时击中了该网站,以便与玩家A一起检查他们的战斗状态。战斗需要更新有关玩家A的信息。如果我没有正确编码,A的数据可能搞砸了。

在这种情况下我有两场比赛,每场比赛都有不同的解决方案和不同的问题。其中一个使用锁定,因此当用户访问站点时,他们获取数据库行的锁定,读取数据以获取成功获取的锁定,然后编写更改并释放锁定。但有时候,由于原因仍然未知,这会失败并且锁定会永久停滞,用户抱怨并且我们必须手动修复它。我的另一个游戏使用一个守护进程来执行这些事务,这个问题几乎没有实际意义,因为只有一个进程可以进行这些更改。但是玩家仍然可以同时做其他事情,并可能导致同样的问题。

我已经阅读了一些关于此的不同解决方案,例如乐观或基于时间戳的控件。我想问一下:

  1. 其中哪些最常用于像我这样的情况,最容易实现?

  2. 我的下一个项目是使用Kohana(PHP)及其ORM,因此默认情况下我的db写入将采用“只覆盖所有这些字段”的形式。我是否需要为此编写自己的更新查询,还是可以获得与ORM兼容的解决方案?

  3. 涉及多个表的交易怎么样?战斗的结果必须改变战斗表和玩家信息表,可能还有更多的东西。哪种解决方案更易于使用?我的所有表都需要事务时间戳列吗?

  4. 很多这些解决方案都说当发生冲突时,重试或忽略。这对我意味着什么? “重试”是否意味着重新启动我的整个脚本,这会给用户带来额外的加载时间?我不认为忽略是一个有效的选项,因为事件必须在某个时刻执行。在我发现的其他问题中,向用户提出冲突错误通常是一个有效的选择 - 对我而言,事实并非如此。

  5. 并发控制的性能影响是什么 - 它甚至值得吗?

1 个答案:

答案 0 :(得分:0)

我认为您所寻找的内容已包含在您的问题中:交易。 如果您使用的是MySQL,则需要使用innoDb引擎设置表以便能够使用事务。一些文档:

尽可能不要尝试重新发明轮子。