【发布时间】:2013-01-17 12:08:10
【问题描述】:
我需要一些关于SELECT FOR UPDATE (resp. LOCK IN SHARE MODE) 的帮助。
我有一个包含大约 400 000 条记录的表,我需要在每一行上运行两个不同的处理函数。
表结构是这样的:
data (
`id`,
`mtime`, -- When was data1 set last
`data1`,
`data2` DEFAULT NULL,
`priority1`,
`priority2`,
PRIMARY KEY `id`,
INDEX (`mtime`),
FOREIGN KEY ON `data2`
)
功能有点不同:
-
第一个函数 - 必须在所有记录上循环运行(非常快),应该根据
priority1选择记录;设置data1和mtime -
第二个函数 - 每条记录只运行一次(非常慢),应该根据
priority2选择记录;设置data1和mtime
他们不应该同时修改同一行,但是选择可能会在他们两个中返回一行(priority1 和 priority2 具有不同的值),如果是这种情况,事务等待是可以的(我希望这将是唯一会阻塞的情况)。
我正在根据以下查询选择数据:
-- For the first function - not processed first, then the oldest,
-- the same age goes based on priority
SELECT id FROM data ORDER BY mtime IS NULL DESC, mtime, priority1 LIMIT 250 FOR UPDATE;
-- For the second function - only processed not processed order by priority
SELECT if FROM data ORDER BY priority2 WHERE data2 IS NULL LIMIT 50 FOR UPDATE;
但我遇到的是每次只返回一个查询。
所以我的问题是:
- 是否可以在不同行的两个独立事务中获取两个独立锁(在同一个表中)?
- 我在第一个和第二个查询之间是否有那么多冲突(我在调试时遇到了麻烦,任何关于如何调试
SELECT ... FROM (SELECT ...) WHERE ... IN (SELECT)的提示将不胜感激)? -
ORDER BY ... LIMIT ...会引起任何问题吗? - 索引和键会导致任何问题吗?
【问题讨论】:
-
什么表类型? MyISAM 还是 InnoDB?据我所知,只有 InnoDB 具有行级锁定。 MyISAM 只有表级锁定。
-
我明白了……你的桌子上有索引吗?
-
@Mt.Schneiders 是的,我愿意。我已将它们添加到架构中。感谢您的关注。
标签: mysql transactions innodb table-locking