【发布时间】:2018-03-09 16:19:07
【问题描述】:
我正在使用 InnoDB 引擎为 MySQL 数据库 v5.7.16 实现一个基于表的自定义序列生成器。sequence_table 如下所示:
+-------------+-----------+
|sequence_name|next_value |
+-------------+-----------+
| first_seq | 1 |
+-------------+-----------+
| second_seq | 1 |
+-------------+-----------+
sequence_name 列是主键。
此序列表包含针对不同消费者的多个序列。
我使用以下策略进行序列更新:
- 选择当前序列值:
select next_val from sequence_table where sequence_name=?。 - 将分配大小添加到当前序列值。
- 如果当前值与第一步中选择的值匹配,则更新序列值:
update sequence_table set next_val=? where sequence_name=? and next_val=?。 - 如果更新成功,则返回增加的序列值,否则从步骤 1 开始重复该过程。
文档包含以下信息:
UPDATE ... WHERE ... 在每条记录上设置一个排他的下一个键锁 搜索遭遇。但是,只需要一个索引记录锁 for 使用唯一索引锁定行以搜索 独特的行。 14.5.3 Locks Set by Different SQL Statements in InnoDB
粗体部分有点混乱。
如您所见,我匹配UPDATE 语句的WHERE 子句中的主键。
是否有可能搜索可能会遇到多条记录并因此锁定此序列表中的多行?
也就是说,算法第三步的更新会阻塞一行还是多行?
【问题讨论】:
-
据我阅读this 了解到,它会锁定多行。我也相信你可以通过Isolation Levels控制行为。
-
您是否正在尝试重新创建
auto_increment而没有所谓的间隙? -
@flip,
next-key lock locks only one index record and the gap before it。这是一种预期的行为,因为我没有定期向该表中插入任何内容,这意味着下一个键锁将在更新期间仅锁定一个索引记录(=一行)。但是搜索部分对我来说还不清楚。 -
@N.B.,应用程序代码需要有可能决定使用哪个序列来获取下一个值,
auto_increment不符合我的需要。在 PostgreSQL 中,我只有两个序列来完成这个。 -
你会过得很糟糕。我不想暗示你应该使用
auto_increment。祝你好运,真的。