我正在製作一個多人遊戲,其中有一個類似大堂的區域,玩家選擇「扇區」進入。大廳網關由PHP支持,而實際的遊戲則由一個或多個Java服務器處理。數據存儲是MySQL。插入一行並避免競爭條件(PHP/MySQL)
快樂的路徑: 玩家選擇一個部門並告訴他想要進入的大廳。 大堂會檢查這是否正常,包括檢查該部門中是否有太多玩家(比較該部門的扇區分配入口數與該部門的max_players值)。 玩家被添加到sector_assignments表中,並將其與該部門配對。玩家客戶端會收到一個密碼,讓他連接到合適的遊戲服務器。
比賽條件: 如果兩個玩家要求在同一時間訪問同一個區域,我可以設想一個情況,他們都被添加了,因爲在他們的支票開始時有一個空間可用並且超過了最大玩家。
是sector_assignments上的最佳解決方案LOCK TABLE?還有其他選擇嗎?
行鎖定對此不起作用,因爲計數器不是行數據的一部分,它是通過在由扇區分組的sector_assignments表上調用COUNT來確定的。看起來我需要在檢查用戶數量之前鎖定表格,然後插入,然後解鎖。 – justkevin 2010-05-12 01:20:24
我明白你的意思了,在你的情況下計數是一個計算值。我有點固執,但如果我是你,我會在扇區的'max_value'旁邊添加一個'current_value'列。這是對數據的輕微的非規範化,但它意味着:沒有'count(*)',也沒有'lock'。只需使用樂觀鎖定,並確保更新'current_value'並在同一事務中的'sector_assignment'中插入行。 – ewernli 2010-05-12 07:22:53