使用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
相关产品推荐
相关产品推荐

