baomidou / mybatis-plus

An powerful enhanced toolkit of MyBatis for simplify development
https://baomidou.com
Apache License 2.0
16.42k stars 4.31k forks source link

乐观锁OptimisticLockerInnerInterceptor, 即使更新失败, 实体版本号也会自增 #5805

Open 9talk opened 11 months ago

9talk commented 11 months ago

当前使用版本(必填,否则不予处理)

mybatis-plus-boot-starter: 3.5.4.1

该问题是如何引起的?(确定最新版也有问题再提!!!)

对版本号实现自增时, 没判断更新状态? 即使更新失败版本号也会改变!

这会导致旧数据只要能够成功更新到最新版本号, 下次更新就会能够成功更新!

重现步骤(如果有就写完整)

  1. 插入一篇数据, 此时库中版本号为0
  2. 模拟某一台机器获取最新版本数据插入成功, 版本号自增1, 这个是正确的
  3. 模拟一台机器获取了旧数据, 这个旧数据的版本号为0, 对旧数据进行操作会发现更新失败了, 但是旧数据的版本号自增了!!

    //  ReportSubmissionHistoryPO po = new xxx();
    // 插入新数据
    mapper.insert(po);
    
    // 更新状态, 第一次更新, 版本号应该为1
    po.setStatus(SubmissionStatusEnum.PROCESSING.name());
    mapper.updateById(po);
    System.out.println("当前机器更新成功的版本号: " + po.getVersion());  // >>> 当前机器更新成功的版本号: 1
    
    // 测试其他机器版本落后的情况, 版本号操作-1
    po.setStatus(SubmissionStatusEnum.PROCESSING.name());
    po.setVersion(po.getVersion() - 1);
    
    System.out.println("其他机器落后的版本号更新前: " + po.getVersion()); // >>>  其他机器落后的版本号更新前: 0
    int success = mapper.updateById(po);
    System.out.println("其他机器更新标识: " + success);// >>> 其他机器更新标识: 0, 更新失败
    System.out.println("其他机器落后的版本号更新后: " + po.getVersion()); // >>>  其他机器落后的版本号更新后: 1

报错信息

无报错

9talk commented 11 months ago
图片