我能保证在 mysql 中使用单个插入语句获得连续的 id 吗?

2023-12-12

我使用单个 INSERT 查询插入 1000 行。查询返回第一个插入行的 id。假设所有其他行都有 id 是否可以保存firstId + i考虑到可能有多个插入查询同时运行?


或许。通常是的,但在很多情况下这是不可靠的。

MySQL JDBC 驱动程序假设当您执行批量插入时,一批生成的自动增量值是连续的。

请参阅中的代码java.com.mysql.cj.jdbc.StatementImpl.getGenerateKeysInternal()

简化逻辑,相关位是:

long beginAt = getLastInsertID();
for (int i = 0; i < numKeys; i++) {
    row[0] = StringUtils.getBytes(Long.toString(beginAt));
    beginAt += this.connection.getAutoIncrementIncrement();
}

因此它从第一个插入行的 id 开始,并且假设后续生成的 id 值就是下一个numKeys值,增加auto_increment_increment配置设置(默认为 1)。

这会出错吗?是的,在某些情况下。例如:

  • 如果你做多行INSERT,为某些行指定 NULL,并为同一行中的其他行指定实整数值INSERT语句中,JDBC 驱动程序假设所有值都是在返回值之后的连续值LAST_INSERT_ID()是不正确的。

  • 如果你做多行INSERT...ON DUPLICATE KEY UPDATE or REPLACE如果某些行存在而其他行不存在,它将错误地报告一组连续生成的键。

  • 如果你设置innodb_autoinc_lock_mode = 2(“交错”锁模式),那么并发运行的多行 INSERT 语句可能不是连续的。只要有可能,它们都会生成 id 值,并且这将不可预测地交错,就像洗一副牌的两半一样。看https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我能保证在 mysql 中使用单个插入语句获得连续的 id 吗? 的相关文章

随机推荐