2010-08-24 62 views
2

我正在为网络写一个策略类的多用户游戏。它有一个playfield(X乘Y的方格),我计划将其序列化并存储在MySQL(innodb)数据库的BLOB中,每个正在进行的游戏一行。这是否足够,还是我有竞争条件?

我现在试图找出一种更好的方法来保持数据库更新与对赛场的任何更改,并在同一时间找到一个方便的解决方案,以便如何处理事件发生在加载之间的时间范围该页面,并实际采取行动。
我不使用AJAX。

每场比赛最多有20名选手,每名选手在24小时内进行1到10次移动,所以这是一个“慢”的比赛。

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

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

  1. 开始交易。从表
  2. 负荷赛场如果校验和不同 - 回滚和更新用户查看
  3. 如果校验不变 - 更新表,并提交更改

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

感谢您的所有建议。

回答

2

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

+0

太好了。我的“算法”看起来是否理智?我的意思是,我保证同时执行上面两个步骤的两个(或任意多个)线程(使用'FOR UPDATE')将被序列化,因此每次只有一个进程可以访问相关的行? – MattBianco 2010-08-25 07:11:17

+0

是的,一旦一个线程在该行上发出SELECT FOR UPDATE,所有其他线程将在它们的SELECT FOR UPDATE上停顿,直到该事务完成。然后接下来的线程将读取更新的行。 – nathan 2010-08-25 14:21:56

0

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

​​

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

不要忘了以后解锁!

+0

LOCK TABLE会起作用,但是比必要的更加沉重。最好只锁定你需要的行。 – nathan 2010-08-24 16:39:21