2010-08-24 4 views
2

Я пишу стратегию многопользовательской игры для Интернета. В нем есть игровое поле (X по квадратам Y), которое я планирую сериализовать и хранить в BLOB в базе данных MySQL (innodb), по одной строке для каждой текущей игры.Достаточно ли этого, или у меня есть условия гонки?

Теперь я попытаюсь найти хороший способ сохранить базу данных обновленной с любыми изменениями в игровом поле и в то же время найти удобное решение, как обрабатывать вещи, которые происходят с игровым полем в промежутках времени между загрузкой страницу и фактически сделать ход.
Я не использую AJAX.

В каждой игре будет не более 20 игроков, каждый игрок делает от 1 до 10 ходов за 24 часа, поэтому это «медленная» игра.

Мой план (пока) заключается в том, чтобы также хранить контрольную сумму для игрового поля рядом с блобом и сравнивать состояние базы данных с загруженным состоянием, прежде чем пытаться внести изменения в игровое поле.

О чем беспокоиться - как предотвратить условия гонки.
Является ли это достаточно, чтобы:

  1. Начало транзакции. игровое поле
  2. груза из таблицы
  3. если контрольная сумма отличается - откат и обновления пользователей просматривать
  4. если контрольная сумма без изменений - таблица обновления и совершающих изменения

ли BEGIN TRANSACTION достаточно, чтобы блокировать гонки, или я нужно сделать что-то еще на шаге 2, чтобы показать мое намерение обновить таблицу?

Благодарен за все советы.

ответ

2

Если вы используете SELECT ... FOR UPDATE при загрузке игрового поля из базы данных, он блокирует другие выборы, пока вы не совершите или откатите транзакцию.

+0

Отлично. Является ли мой «алгоритм» здоровым? Я имею в виду, что я гарантирую, что два (или любое число) потоков, которые одновременно выполняют 2 шага выше (с 'FOR UPDATE'), будут сериализованы, так что только один процесс за один раз может получить доступ к соответствующей строке? – MattBianco

+0

Да, когда один поток выдает SELECT FOR UPDATE в строке, все остальные потоки останавливаются на их SELECT FOR UPDATE, пока эта транзакция не будет завершена. Затем следующий поток, который пройдет, прочитает обновленную строку. – nathan

0

Нет. Вам необходимо будет выдать команду LOCK TABLES для таблиц, необходимых для защиты от противоречивых обновлений. Это будет выглядеть примерно так ...

LOCK TABLE my_table WRITE; 

Более подробную информацию можно найти здесь ... http://dev.mysql.com/doc/refman/5.1/en/lock-tables.html

Не забудьте открыть их потом!

+0

LOCK TABLE будет работать, но более тяжелый, чем необходимо. Лучше блокировать только строки (строки), которые вам нужны. – nathan

Смежные вопросы