MySQL InnoDB只锁定受影响的行?

时间:2009-10-19 19:35:13

标签: sql mysql innodb rowlocking

我有一个包含用户的InnoDB表,如下所示:

+--------------+-----------------------+
| user_id      | name                  |
+--------------+-----------------------+
| 1            | Bob                   |
| 1            | Marry                 |
| 2            | Bob                   |
| 1            | John                  |
| 3            | Bob                   |
| 2            | Marry                 |
+--------------+-----------------------+

在每个插入上,我将user_id增加1,例如,Bob的下一个user_id将为4

我使用此查询来执行此操作:

INSERT INTO users (user_id, name)
SELECT 1 + coalesce((SELECT max(user_id) FROM users WHERE name='Bob'), 0), 'Bob';

现在我需要确保两个不同的用户不会同时添加“Bob”。我不希望任何两个Bobs与user_id 4.每个Bob的用户ID必须不同。

当运行上面的插入查询时,是否可以写入并更新锁定Bob的所有行?我无法锁定整个表,因为许多其他用户仍然需要对其行进行完全访问。此外,所有行都应始终可读。我该怎么做?

3 个答案:

答案 0 :(得分:3)

要解决问题的第一部分, 在user_id和name上创建唯一索引。

alter table `users` add unique index ak_user_id_name(user_id,name);

这样可以防止重复的user_id,名称记录。

答案 1 :(得分:3)

这个问题的答案与this one相同。与基于语句的二进制日志记录的安全性相比,InnoDB将锁定更多行。

解决方案:使用基于行的二进制日志记录和读取提交的隔离级别。

答案 2 :(得分:2)

在这里假设InnoDB,您可以在选择行时使用SELECT ... LOCK IN SHARE MODE锁定行。