GORM OnConflict Clause未自动更新乐观锁Version字段问题咨询
问题分析
当使用GORM的OnConflict{UpdateAll: true}处理冲突时,乐观锁的Version字段未自动递增,核心原因有两点:
UpdateAll的底层逻辑是生成UPDATE ... SET col = EXCLUDED.col的SQL,而你传入的testUpdateEntity中Version未赋值(默认值为0),执行后会把数据库里的Version覆盖为0,而非递增。- GORM的乐观锁插件依赖
BeforeUpdate钩子触发Version递增,但Create结合OnConflict的冲突更新流程不会触发BeforeUpdate钩子,自然无法自动完成Version的递增操作。
解决方案
无需逐个指定字段,可通过DoUpdates结合gorm.Expr实现批量更新所有字段+Version自动递增:
dres := u.db.WithContext(context.TODO()).Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, // 指定触发冲突的主键列 DoUpdates: clause.Assignments(map[string]interface{}{ "*": gorm.Expr("EXCLUDED.*"), // 批量更新所有字段为传入实体的新值 "version": gorm.Expr("version + 1"), // 手动实现Version递增 }), }).Create(testUpdateEntity)
方案说明
EXCLUDED.*会引用冲突时传入的新实体的所有字段值,彻底避免逐个指定字段的繁琐操作。version + 1直接在SQL层面完成Version递增,替代乐观锁钩子的自动处理逻辑。- 该方式既满足批量更新需求,又能保证Version字段按预期递增。
补充说明
GORM的乐观锁插件目前(v1/v2版本)确实未适配OnConflict冲突更新场景,无法自动触发Version递增,必须手动通过SQL表达式处理。
内容的提问来源于stack exchange,提问作者hatake kakashi
相关产品推荐
相关产品推荐

