【问题标题】:mySQL - Table locking vs Row lockingmySQL - 表锁定与行锁定
【发布时间】:2009-11-12 23:25:52
【问题描述】:

应用说明

我有一个表,它存储代表地图上区域的 ID。每张地图包含 1000 个区域。 领土是地图中任意数量的区域。用户争夺地图不同区域的所有权。

数据库设计

目前我有一张地图表、一张领土表和一张地区表。

tblMaps: MapID, MapName

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

tblAreas: AreaID (1-1000), TerrID

目前 tblAreas 仅在地图中存储被占用的区域 - 每张地图不包含 1000 条记录,无论是否有人拥有它。

当用户尝试获取某些区域的所有权时,应用程序必须连接三个表并查询该地图中的所有已占用区域。如果其中任何一个被采取,它应该拒绝他的所有权尝试。如果所有区域都是空闲的,则应创建一个新区域并将相关区域添加到 tblAreas 中。

问题

我意识到我需要一个基于交易的系统,这样两个用户就不会试图同时“拥有”该区域。现在,据我所知,我必须锁定整个 Area 表,查询这些区域是否空闲,插入一个新区域及其区域,提交它并解锁表......或者 Areas 表应该包含所有 1000每个地图的区域和锁定应该只应用于该地图的行。

希望有更好的选择,因为据我所知。锁定表格将意味着在那一秒内所有区域数据都无法访问,或者在行锁定的情况下,表格充满了无用的未占用区域。

【问题讨论】:

  • 我很困惑——究竟什么是区域?地图,我明白了。领土只是地图的细分,可以拥有(我认为?)。一个区域是一组领土吗?还是一个区域是一组区域?
  • 抱歉,我已经编辑过了。地图由 1000 个区域组成。领土是一个用户拥有的相邻区域的集合。

标签: mysql database transactions insert


【解决方案1】:

如果您在 tblAreas.AreaID 上有一个索引,那么任何包含 WHERE tblAreas.AreaID in (...) 的事务都会锁定这些条目的索引。行本身是否存在并不重要。该锁将阻止另一个事务为这些 ID 插入任何条目。所以我认为你不需要做任何你的建议。只需查询是否所有区域都可用于您的领土,即可获得自动插入领土所需的锁。

这可能有点问题,因为您的区域 ID 在游戏范围内不是唯一的,因此在不同地图中具有相同 ID 的区域之间可能会出现一些错误的序列化。将 mapID 添加到您的 tblAreas 表可能会有所帮助,这样您就可以创建一个 (mapID, areaID) 索引来代替查找,这将避免索引上的错误冲突。 (这会使您的架构非规范化,您可能出于其他原因不想这样做。)

【讨论】:

  • 我不能只在 tblTerritories 中锁定 mapID 以阻止任何人插入新条目吗?非规范化是如此诱人......它会使可用区域的查询变得更加容易(只需查询 tblarea.. 而不是将三个表连接在一起)......但我认为它的效率会降低。你怎么看?
  • 是的,我猜如果您通过 mapID 查询 tblTerritories 会阻止其他人在您的交易过程中插入另一个区域。
猜你喜欢
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
  • 2011-12-30
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多