2010-08-24 28 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