Mybatis-Plus 插件——乐观锁

模拟问题场景

场景:

1.商品原先价格100
2.boss通知小李将商品价格加50
3.boss觉得加到150,价格太高,通知小王降价30
4.小李和小王同时查看商品价格为100,小李将价格改为150,小王将价格改为70
5.最终结果商品价格为70,而boss实际想设定的值是120

代码模拟问题:

 @Test
    public void testOptimisticLock() {
        //小李查询商品价格
        Product productLi = productMapper.selectById(1);
        Integer priceLi = productLi.getPrice();
        System.out.println("小李查询商品价格:" + priceLi);

        //小王查询商品价格
        Product productWang = productMapper.selectById(1);
        Integer priceWang = productWang.getPrice();
        System.out.println("小王查询商品价格:" + priceWang);

        //小李涨价50
        priceLi = priceLi + 50;
        productLi.setPrice(priceLi);
        productMapper.updateById(productLi);

        //小王降价30
        priceWang = priceWang - 30;
        productWang.setPrice(priceWang);
        productMapper.updateById(productWang);

        //最终商品价格
        Product product = productMapper.selectById(1);
        System.out.println("最终商品价格:" + product);

    }

结果:

最终商品价格:Product(id=1, name=外星人笔记本, price=70, version=0)

乐观锁解决问题

使用乐观锁中解决上述问题。

乐观锁实现方式:

  • 取出记录时,获取当前 version
  • 更新时,带上这个 version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果 version 不对,就更新失败

Mybatis-Plus 在使用乐观锁插件时,执行更新操作时会判断当前版本号是否和数据库一致,一致就执行更新操作,不一致的话可以重试(再查询一下数据,然后执行更新操作)

Mybatis-Plus 使用乐观锁:

  1. 配置类添加乐观锁插件
  2. 实体类版本号字段添加@Version注解

配置类添加乐观锁插件

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

实体类版本号字段添加@Version

@Data
public class Product {
    private Long id;
    private String name;
    private  Integer price;
    @Version
    private Integer version;
}

测试

 /**
     * 乐观锁解决问题
     */
    @Test
    public void testOptimisticLockPlus() {
        //小李查询商品价格
        Product productLi = productMapper.selectById(1);
        Integer priceLi = productLi.getPrice();
        System.out.println("小李查询商品价格:" + priceLi);

        //小王查询商品价格
        Product productWang = productMapper.selectById(1);
        Integer priceWang = productWang.getPrice();
        System.out.println("小王查询商品价格:" + priceWang);

        //小李涨价50
        priceLi = priceLi + 50;
        productLi.setPrice(priceLi);
        productMapper.updateById(productLi);

        //小王降价30
        priceWang = priceWang - 30;
        productWang.setPrice(priceWang);
        int i = productMapper.updateById(productWang);
        if(i == 0) {
            //重试
            Product productWa = productMapper.selectById(1);
            productWa.setPrice(productWa.getPrice() - 30);
            productMapper.updateById(productWa);
        }

        //最终商品价格
        Product product = productMapper.selectById(1);
        System.out.println("最终商品价格:" + product);
    }

结果:

最终商品价格:Product(id=1, name=外星人笔记本, price=120, version=2)

posted @ 2023-05-13 17:04  享受生活2023  阅读(83)  评论(0编辑  收藏  举报