赞
踩
本章导学:
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前 version
- 更新时,带上这个 version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果 version 不对,就更新失败
我们先看一个场景:
某公司产品销量不好,于是老板吩咐小王把产品定价下调50元,小王一口答应了下来,但是小王还在摸鱼,没有马上去修改产品的定价。过了一会老板觉得下调50元太亏了,于是吩咐另外一个员工小白去把产品定价下调30元。不巧的是,小王和小白先后对这条数据进行了更新,于是产品价格被调低了80元,老板亏死了~。
我们用代码模拟一下这个场景
我们观察一下sql语句
那如果去解决这个并发冲突呢?我们可以采取以下的方法(乐观锁)
我们新建一个配置类,添加乐观锁拦截器
- package com.brrbaii.Config;
- import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
- import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
- import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- @Configuration
- public class MpConfig {
- @Bean
- public MybatisPlusInterceptor mybatisPlusInterceptor(){
- //1,定义Mp拦截器
- MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
- //2,添加具体的拦截器,这里添加的为分页拦截器
- mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
- //3,添加乐观锁拦截器
- mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
- return mybatisPlusInterceptor;
- }
-
- }

在数据库和实体类上各自添加一个Version字段
重新执行测试方法
- @Test
- public void test02(){
- //需求:原价7800,最终降价为7770
- //小王进行数据
- Dish dishAA = dishMapper.selectById(1397849739276890114l);
-
- //小白进行查询
- Dish dishBB = dishMapper.selectById(1397849739276890114l);
-
- //小王修改价格,下调50元
- dishAA.setPrice(dishAA.getPrice().subtract(new BigDecimal(50)));
- dishMapper.updateById(dishAA);
- //小白修改价格,下调30元
- dishBB.setPrice(dishAA.getPrice().subtract(new BigDecimal(30)));
- dishMapper.updateById(dishBB);
- }

小王执行的修改语句 :
小王此时进行修改会先判断version是否等于从数据里查出来的version,然后对version自增1
小白执行的修改语句:
由于小王操作后,version已经从0加到1了,所以小白的where version = 0判断为false,更新失败
在MybatisPlusInterceptor添加乐观锁拦截器(OptimisticLockerInnerInterceptor)- 在实体类和数据库上分别添加version字段
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。