【发布时间】:2011-05-07 08:02:10
【问题描述】:
还有一些其他关于并发的 SO 问题,但它们并不能完全解决我的情况。
假设我有一个游戏,用户可以在其中进行互动、打架等等。在任何给定时间,玩家都可能参与与其他玩家的多次互动,所有人都可以看到事件的发生。当这些玩家中的任何一个访问该网站时,它需要更新所涉及的所有数据并将其显示给用户。
示例情况:玩家 A 正在与玩家 B 战斗,并且在这场战斗中每隔几分钟就会发生一次事件。同时,玩家 A 也在与玩家 C 交互。运气不好的是,这两个交互的事件恰好在同一秒发生。
当那一秒到来时,再次碰巧,玩家 B 和玩家 C 同时访问该站点,以检查他们与玩家 A 的战斗状态。战斗需要更新玩家 A 的信息。如果我编码不正确,A的数据可能会乱码。
我有两场比赛遇到这种情况,每场比赛都有不同的解决方案和不同的问题。其中一个使用锁,因此当用户访问该站点时,他们会在数据库行上获取锁,读取他们成功获取的锁的数据,然后写入更改并释放锁。但有时,出于未知的原因,这会失败并且锁会永远卡住,用户抱怨,我们必须手动修复它。我的另一个游戏使用守护进程来执行这些事务,使问题(几乎)没有实际意义,因为只有一个进程会进行这些更改。但玩家仍然可以同时做其他事情,并可能导致同样的问题。
我已经阅读了一些关于此问题的不同解决方案的信息,例如乐观控制或基于时间戳的控制。我想问一下:
其中哪些最常用于像我这样的情况,哪些最容易实现?
我的下一个项目是使用 Kohana (PHP) 及其 ORM,因此我的 db 写入默认情况下采用“仅覆盖所有这些字段”的形式。我需要为此编写自己的更新查询,还是可以获得与 ORM 兼容的解决方案?
涉及多个表的事务怎么办?战斗的结果必须改变战斗表,玩家信息表,可能还有更多的东西。哪些解决方案在这里更容易使用?我的所有表都需要事务时间戳列吗?
这些解决方案中的很多都表示,当发生冲突时,要么重试,要么忽略。这对我意味着什么? “重试”是否意味着重新启动我的整个脚本,这会导致用户额外的加载时间?我不认为忽略是一个有效的选择,因为事件必须在某个时候执行。在我发现的其他问题中,向用户显示冲突错误通常是一个有效的选项 - 对我来说不是。
并发控制对性能有何影响 - 是否值得?
【问题讨论】:
标签: php database web-applications concurrency