处理 AUTO_INCREMENT 字段的并发问题,核心在于:数据库本身已经为 AUTO_INCREMENT 做了并发安全设计,但你仍需要理解其机制、避免误用和踩坑。下面从原理、常见场景和最佳实践来系统说明。
InnoDB 中:AUTO_INCREMENT 的生成是自增锁(AUTO-INC Locking)保护的,不存在并发重复值问题。
| 场景 | 是否安全 | 说明 |
|---|---|---|
| 多线程同时 INSERT | ✅ 安全 | 不会生成重复 ID |
| 高并发写入 | ✅ 安全 | 不会冲突 |
| 回滚事务 | ⚠️ 值可能“浪费” | 已生成但不会回滚 |
✅ 结论:
AUTO_INCREMENT 不会发生并发重复值问题
INSERT ... VALUES (...)
ROLLBACK;
✅ 这是设计行为,不是并发问题。
INSERT INTO t(name) VALUES ('test');
SELECT MAX(id) FROM t;
并发下:
MySQL
SELECT LAST_INSERT_ID();
JDBC
ResultSet rs = ps.getGeneratedKeys();
✅ 这是 当前连接、当前事务安全 的
如果你自己实现类似:
SELECT counter FROM counter_table WHERE id=1 FOR UPDATE;
UPDATE counter_table SET counter = counter + 1;
✅ 直接交给 AUTO_INCREMENT ❌ 不要自己实现自增
✅ 更好方案:
AUTO_INCREMENTALTER TABLE t AUTO_INCREMENT = 1;
✅ 除非数据迁移,否则不要用
AUTO_INCREMENT 不适合跨实例
| 场景 | 方案 |
|---|---|
| 单库 | AUTO_INCREMENT ✅ |
| 分库分表 | 雪花算法(Snowflake) |
| 高性能分配 | 号段模式(Leaf / Baidu UidGenerator) |
| 全局唯一 | UUID / ULID |
MySQL 8.0 可配置:
SHOW VARIABLES LIKE 'innodb_autoinc_lock_mode';
| 值 | 含义 |
|---|---|
| 0 | 传统表锁(慢) |
| 1 | 默认,混合模式 ✅ |
| 2 | 无锁(仅适合 binlog=row) |
✅ 一般不用改
AUTO_INCREMENT 本身是并发安全的,真正的问题往往不在自增,而在“如何获取、使用和扩展它”。
LAST_INSERT_ID() / getGeneratedKeys()如果你有 具体场景(如:分库分表 / MyBatis / 高并发秒杀 / 多实例部署),我可以给你更针对性的方案和代码示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。