在面试过程中,我们经常会被问道乐观锁,悲观锁,其实原理非常简单
乐观锁 OptimisticLockerInnerInterceptor
顾名思义十分乐观,它总是认为不会出现问题,无论干什么都不会上锁!如果出现问题就再次更新测试
这里引出 旧version 新version
乐观锁:当要更新一条记录的时候,希望这条记录没有被别人更新乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
乐观锁:1、先查询,获得版本号 version = 1 -- A update user set name = "xiaoshaung",version = version + 1 where id = 2 and version = 1 -- B 线程抢先完成,这个时候 version = 2 ,会导致 A 修改失败! update user set name = "小爽",version = version + 1 where id = 2 and version = 1
测试Mybatis-Plus的乐观锁实现
1、给数据库中增加version字段
2、实体类加对应的字段
//乐观锁version注解 @Version private Integer version;
3、注册组件
// 这个扫描本来是在我们MybatisPlusApplication 主启动类中,现在我们把它放在配置类中
// 扫描mapper文件夹
@MapperScan("com.shuang.mapper")
@EnableTransactionManagement // 自动开启事务管理
@Configuration // 配置类
public class MybatisPlusConfig {
// 注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
4、测试一下乐观锁的使用
// 测试乐观锁单线程成功
@Test
public void testOptimisticLock(){
// 1、查询用户信息
User user = userMapper.selectById(1);
// 2、修改用户信息
user.setName("xiaoshaung");
user.setEmail("123123132@qq.com");
// 3、执行更新操作
userMapper.updateById(user);
}
测试一下多线程的使用
// 测试乐观锁多线程失败 多线程
@Test
public void testOptimisticLock2(){
// 线程1
User user = userMapper.selectById(1);
user.setName("xiaoxiao111");
user.setEmail("123123132@qq.com");
// 模拟另外一个线程执行了插队操作
// 线程2
User user2 = userMapper.selectById(1);
user2.setName("xiaoxiao222");
user2.setEmail("123123132@qq.com");
userMapper.updateById(user2);
// 自旋锁来多次尝试提交
userMapper.updateById(user);
}
悲观锁
顾名思义十分悲观,它总是认为会出现问题,无论干什么都上锁!再去操作
我们这里主要讲究乐观锁机制



