我有一个包含用户的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的所有行?我无法锁定整个表,因为许多其他用户仍然需要对其行进行完全访问。此外,所有行都应始终可读。我该怎么做?
答案 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锁定行。