乐观锁
在面试过程中,我们经常会被问到乐观锁,悲观锁!这个其实非常简单!
乐观锁:故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,再次更新值测试。
悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作!
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
简单解释:
乐观锁:1、先查询,获得版本号version =1
--A线程
update user set name ="kuangshen",version = version +1
where id = 2 and version = 1
--B线程抢先完成,这个时候version =2,会导致A修改失败!
update user set name ="kuangshen",version = version +1
where id =2 and version =1
测试一下MP的乐观锁插件
1、给数据库中增加version字段!
2、我们实体类加对应的字段
@Version//乐观锁Version注解
private Integer version;
3,注册组件:
package com.config; import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; @MapperScan("com.hui.mapper")//把扫描mapper接口的注解移动到这个配置类上面 @EnableTransactionManagement//事务注解默认开启 @Configuration//配置类 public class MybatisplusConfig { //注册乐观锁插件 @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }
4.测试:
乐观锁的情况下正常更新成功的情况:
//测试乐观锁成功
@Test
void testOptimisticLocker(){
User user = userMapper.selectById(5L);
Integer version = user.getVersion();
System.out.println("第一次查询封装到user中的版本是:"+version);
//接下来进项修改
user.setAge(23);
user.setName("本杰明");
userMapper.updateById(user);
}
结果成功:
测试乐观锁失败的情况:
//测试乐观锁失败
@Test
void testOptimisticLocker2() {
User user1 = userMapper.selectById(1L);
user1.setName("瓜瓜");
//接下来这个操作模拟线程2的操作
User user2 = userMapper.selectById(1L);
user2.setName("瓜瓜2");
userMapper.updateById(user2);//这个时候version就会更新成2
//然后下面的user的更新操作因为版本还停留在1,所以会更新失败
userMapper.updateById(user1);
//所以最后版本是2,名字是瓜瓜2
}
数据库中的结果: