MyBatis-Plus 乐观锁失效:为什么版本字段没有自增?

MyBatis-Plus 乐观锁失效:为什么版本字段没有自增?
最新回答
探春

2022-11-07 07:16:33

MyBatis-Plus乐观锁失效且版本字段未自增的问题,通常由以下原因导致。以下是详细分析和解决方案:

1. 数据库version字段为null
  • 原因:乐观锁机制依赖数据库记录的version字段与实体类中的version值进行比较。若数据库中该字段初始值为NULL,首次更新时无法触发版本号自增逻辑。
  • 解决方案

    确保数据库表结构中version字段有默认值(如DEFAULT 0)。

    初始化数据时显式设置version=0。

2. 实体类未正确配置@Version注解
  • 原因:MyBatis-Plus通过@Version注解标识乐观锁字段。若未添加或注解使用不当,框架无法识别版本控制字段。
  • 解决方案:@Datapublic class Goods { @Version private Integer version; // 确保字段类型为Integer/Long等数值类型 // 其他字段...}

    注意:字段类型应为数值类型(如Integer),避免使用String。

3. 未启用乐观锁插件
  • 原因:MyBatis-Plus的乐观锁功能需通过插件显式启用,否则拦截器不会处理版本号逻辑。
  • 解决方案:在配置类中注册乐观锁插件:@Configurationpublic class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }}
4. 更新操作未包含version字段
  • 原因:若更新时未将实体类的version字段值传递给SQL,数据库无法比较版本号。
  • 解决方案

    确保查询时加载了version字段(如示例代码中的goodsService.getOne已包含)。

    避免手动拼接SQL绕过框架逻辑。

5. 其他潜在问题
  • 数据库表结构变更:若表结构被修改但未同步到实体类,可能导致字段映射失效。
  • 原生SQL覆盖:使用@Update注解或XML中的原生SQL更新数据时,需手动处理版本号逻辑。
  • 版本冲突:高并发下若多个线程同时读取相同版本号,可能导致后续更新失败(需结合重试机制)。
排查步骤总结
  1. 检查数据库:确认version字段非空且有默认值。
  2. 验证实体类:确保字段标注@Version且类型正确。
  3. 确认插件配置:检查OptimisticLockerInnerInterceptor是否已注册。
  4. 调试SQL日志:开启MyBatis日志,观察更新SQL是否包含version条件(如version = ?)。
  5. 排除并发干扰:单线程测试验证基础逻辑是否生效。

通过以上步骤,通常可定位并解决乐观锁失效问题。核心在于确保数据库字段有值注解配置正确插件生效