2009-11-12 2 views
4

Применение ОписаниеMySql - Таблица блокировки против Роу блокировки

У меня есть таблица, которая хранит идентификаторы, представляющие регион на карте. Каждая карта содержит 1000 областей. Территория - это любое количество областей карты, которая касается. Пользователи борются за владение разными областями карты.

Design Database

В настоящее время у меня есть таблица карт, таблица территорий и таблица областей.

tblMaps: MapID, MapName 

tblTerritories: TerrID (unique game wide), MapID, OwnerID, Status, Modified 

tblAreas: AreaID (1-1000), TerrID 

На данный момент tblAreas хранит только оккупированных районов в пределах карты - она ​​не содержит 1000 записей в карте, независимо от того, если кто-то владеет.

Когда пользователь пытается завладеть некоторыми областями, приложение должно присоединиться к трем таблицам и запросить все принятые области на этой карте. Если кто-либо из них будет принят, он должен отклонить его попытку собственности. Если все области свободны, должна быть создана новая территория, а соответствующая область будет добавлена ​​в tblAreas.

Проблема

я понял, что мне нужна система на основе транзакций, так что два пользователя не пытается «своей» области в то же самое время. Теперь, насколько я вижу, я должен либо заблокировать всю таблицу Area, запрос, чтобы увидеть, свободны ли области, вставить новую территорию и ее область, зафиксировать ее и разблокировать таблицу ... ИЛИ таблица Areas должна содержать все 1000 области каждой карты и блокировка должны быть применены только к строкам этой карты.

Надеюсь, что есть лучший вариант, потому что, насколько я могу видеть. Блокировка таблицы будет означать, что все данные области не доступны для этой секунды или с блокировкой строк в таблице заполнены бесполезными незанятыми областями.

+0

Я смущен - что такое Area, точно? Карту, я понимаю. Территория - это всего лишь подразделение карты и может принадлежать (я думаю?). Является ли Район территорией? Или территория - это группа областей? –

+0

Извините, я его отредактировал .. Карта состоит из 1000 областей. Территория представляет собой совокупность смежных областей, принадлежащих одному пользователю. – Mark

+0

+1 для хорошего вопроса ... –

ответ

1

Если у вас есть индекс на tblAreas.AreaID, любая транзакция, которая включает WHERE tblAreas.AreaID in (...), заблокирует индекс для этих записей. Неважно, существуют ли сами строки или нет. Эта блокировка не позволит другой транзакции вставить любые записи для этих идентификаторов. Поэтому я не думаю, что вам нужно сделать одно из ваших предложений. Просто запрос, чтобы узнать, доступны ли все области для вашей территории, заставит вас заблокировать вас, чтобы вы вставляли свою территорию атомарно.

Это может быть проблемой, поскольку идентификаторы вашей зоны не уникальны, поэтому может быть некорректная сериализация между областями с одинаковым идентификатором на разных картах. Это может помочь добавить mapID в таблицу tblAreas, чтобы вы могли вместо этого индексировать индекс (mapID, areaID), чтобы избежать ложных коллизий в индексе. (Это денормализует вашу схему, которую вы, возможно, не захотите делать по другим причинам.)

+0

Могу ли я не просто заблокировать mapID в tblTerritories, чтобы никто не вставлял новую запись? Денормализация настолько соблазнительна ... это сделало бы запрос доступной области намного проще (просто попросите tblarea .. вместо того, чтобы объединить три таблицы вместе) ... Но я думаю, что это будет менее эффективно. Как вы думаете? – Mark

+0

Да, я думаю, если вы запросите tblTerritories по mapID, чтобы кто-либо еще не вставлял другую территорию во время транзакции. –

+0

+1 за хороший ответ ... –

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