在面试过程中,我们经常会被问道乐观锁和悲观锁,这个其实非常简单。
乐观锁:故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,再次更新值测试。
悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么都会上锁,再去操作。
我们这里主要讲解乐观锁机制。
取出记录时,获取当前 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
测试一下MyBatisPlus的乐观锁插件
2、实体类加对应的字段,并用 @Version标注。
@Version // 乐观锁Version注解 private Integer version;
3、注册组件。
package com.cxy.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration // 配置类
public class MyBatisPlusConfig {
// 注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
4、进行测试。
// 测试乐观锁成功
@Test
public void testOptimisticLocker(){
// 1.查询用户信息
User user = userMapper.selectById(1L);
// 2.修改用户信息
user.setName("xxx");
user.setEmail("3419339201@qq.com");
userMapper.updateById(user);
}
// 测试乐观锁失败,多线程环境下!
@Test
public void testOptimisticLocker2(){
// 线程1
User user = userMapper.selectById(1L);
user.setName("user1");
user.setEmail("2439115397@qq.com");
// 模拟另外一个线程执行了插队操作
User user2 = userMapper.selectById(1L);
user2.setName("user2");
user2.setEmail("2953887629@qq.com");
userMapper.updateById(user2);
userMapper.updateById(user); // 如果没有乐观锁就会覆盖插队线程的值!
}



