乐观锁插件
乐观锁与悲观锁
乐观锁:十分的乐观,它认为不会出现问题,无论干什么都不去上锁, 悲观锁:十分的悲观,它认为总是会出现问题,无论干什么都去上锁,
乐观锁插件
意图:
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
乐观锁原理:
比如我在数据库里要修改一个id=1,并且version=1的一条数据,乐观锁会先去查询id=1的version是否等于1,如果等于就修改,如果不等于就不修改
代码语言:javascript复制--乐观锁 先查询,获得一个可以判断的值
--a线程 执行更新
update user set name=#{name},version=newVersion where id=1 and version = 1
--b线程 抢先在a线程执行完毕之前执行
update user set name=#{name},version=newVersion where id=1 and version = 1
--由于b线程抢先执行了,version的值已经改变不在是1了,但是又有 and version = 1 的限制,所以a线程就不会执行成功 从而保障了线程的安全
MP中的乐观锁插件实现
数据库新增int类型的 version字段默认值为1。
增加pojo实体类的属性,并打上@Version注解
代码语言:javascript复制@Version //乐观锁
private Integer version;
新增MybatisPlusConfig配置类
代码语言:javascript复制@Configuration
@EnableTransactionManagement
public class MybatisPlusConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
测试多线程下的插入操作
代码语言:javascript复制 @Test
void testLocking(){
//线程A
User user = userMapper.selectById(1L);
user.setEmail("4152064@qq.com");
//线程B抢先修改
User user2 = userMapper.selectById(1L);
user2.setEmail("2414506319@qq.com");
userMapper.updateById(user2);
//等待B线程执行完毕在执行A线程
userMapper.updateById(user);
}
}
因为有了乐观锁,当有多个线程对同一个对象进行操作时后操作的线程就无法在继续操作,保证了线程的安全