MyBatis-Plus使用乐观锁具体实现

其实乐观锁很常用不要觉得很难似的,一步步来试一下

乐观锁先修改,更新的时候发现数据已经变了就回滚(check and set),乐观锁一般通过版本号或者时间戳实现。

这里我们使用Mybatis-Plus来进行使用

一.方法一使用 @Version 注解来实现

1.首先你要在你的表中添加一个字段这里我就定义为version用来控制版本

特别注意:

支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime

 2.接着你需要在你这个表的实体类中添加

@Version:可以在实体 bean 中使用@Version 注解,通过这种方式可添加对乐观锁定的支持  
一个类中只能有一个@Version注解  注意此属性 不能用 String  
 @Version
 private Integer version;

 3.在Application容器创建Bean(很重要否则会提示找不到)

@Bean
public MybatisPlusInterceptor myOptimisticLockerInnerInterceptor(){
     MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
     interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
     return interceptor;

 }

 4.最后这里贴一下我的业务处理代码吧,这就灵活使用了

@Override
public CommonResponse buyOne() {

    GoodsInfo goodsInfo = goodsInfoMapper.selectById(1);

    Integer inventoryNum = goodsInfo.getInventoryNum();
    if (inventoryNum <= 0){
        log.error("没有库存了!当前仓库为:"+inventoryNum);
        return CommonResponseUtils.dataIsNullError("没有库存了!");
    }

    int newInventoryNum= inventoryNum - 1;//修改库存
    goodsInfo.setInventoryNum(newInventoryNum);

    int update = goodsInfoMapper.updateById(goodsInfo);//更新
    if (update==1){
         log.info("下单成功!当前仓库为:"+newInventoryNum);
         return CommonResponseUtils.success("下单成功!当前仓库为:"+newInventoryNum);
    }
        log.error("下单失败!当前仓库为:"+newInventoryNum);
        return CommonResponseUtils.dataIsNullError("下单失败!当前仓库为:"+newInventoryNum);
}

 5.先看下我的数据库现在的库存5个

 

 6.然后我用20的并发来测试看看,成功5个其他失败

 再看下数据库,好了很成功!

 二.其实原理还是依旧遵循

乐观锁先修改,更新的时候发现数据已经变了就回滚

我们不使用方法一的@Version,这次相当于自己实现

这里我们就主要靠业务代码来实现了

思路:首先拿到一个库存数量 例如5,更新的时候一定要增加更新条件,那就是只有当前库存是5的时候才可以更新成功。(弊端1:失败次数多,2:如果有人增加库存那么的话。但是还是建议使用version方法一)

@Override
    public CommonResponse buyOne() {
        //查询商品
        GoodsInfo goodsInfo = goodsInfoMapper.selectById(1);
        //检测库存数量
        Integer inventoryNum = goodsInfo.getInventoryNum();//当前库存数量
        if (inventoryNum <= 0){
            log.error("没有库存了!当前仓库为:"+inventoryNum);
            return CommonResponseUtils.dataIsNullError("没有库存了!");
        }

        int newInventoryNum= inventoryNum - 1;//修改库存
        goodsInfo.setInventoryNum(newInventoryNum);

        QueryWrapper<GoodsInfo> query = Wrappers.query();
        query.eq("inventory_num",inventoryNum);

        int update = goodsInfoMapper.update(goodsInfo,query);//更新
        if (update==1){
            log.info("下单成功!当前仓库为:"+newInventoryNum);
            return CommonResponseUtils.success("下单成功!当前仓库为:"+newInventoryNum);
        }
        log.error("下单失败!当前仓库为:"+newInventoryNum);
        return CommonResponseUtils.dataIsNullError("下单失败!当前仓库为:"+newInventoryNum);
    }

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值