You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GORM与Gin创建模型时主键自增异常问题排查

问题原因

这是MySQL InnoDB引擎的自增主键分配机制导致的:
当执行插入语句时,InnoDB会先为这条语句分配自增ID,再执行插入逻辑。如果插入因为唯一键冲突(比如你的Code重复)失败,已经分配的自增ID不会回滚,下一次插入时会直接使用下一个ID,所以就出现了ID从11跳到13的情况。

解决办法

1. 提前校验唯一键(推荐)

在执行插入操作前,先查询数据库检查Code是否已存在,避免触发唯一键冲突,从根源上防止自增ID被浪费。修改仓库层代码:

import "errors"

func CreateSymbol(model models.Symbol) (models.Symbol, error) {
    // 先检查Code是否存在
    var existsSymbol models.Symbol
    result := boot.DB.Where("code = ?", model.Code).First(&existsSymbol)
    if result.RowsAffected > 0 {
        return models.Symbol{}, errors.New("code already exists")
    }

    // 执行插入
    createResult := boot.DB.Create(&model)
    if createResult.Error != nil {
        return models.Symbol{}, createResult.Error
    }

    return model, nil
}

高并发场景下,可配合事务避免竞态条件,或者使用INSERT ... ON DUPLICATE KEY UPDATE语法(需根据业务需求判断是否允许更新操作)。

2. 重置自增计数器(仅测试环境使用)

如果是测试环境,想要让ID连续,可以手动重置自增计数器:

ALTER TABLE symbols AUTO_INCREMENT = 12;

生产环境禁止使用:重置操作会影响并发插入,且自增主键的设计目标是保证唯一性而非连续性,依赖ID连续属于不合理的业务设计。

3. 接受自增ID不连续(最佳实践)

自增主键的核心作用是保证记录唯一性,而非维持连续性。除了唯一键冲突,事务回滚、删除记录等场景都会导致ID断号,业务逻辑不应依赖ID的连续性,可直接接受这种情况。

内容的提问来源于stack exchange,提问作者Duy Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:31:02